Java 在WeakHashMap上重新创建相同的密钥

Java 在WeakHashMap上重新创建相同的密钥,java,weakhashmap,Java,Weakhashmap,根据Java文档: 此类主要用于键对象,其equals方法使用==运算符测试对象标识。一旦丢弃此类键,就无法重新创建,因此无法在WeakHashMap中查找该键 这是否意味着如果我们在weakhashmap中使用objectA作为条目0的键,然后删除该条目TestMapHash虚弱.remove(objectA)我们不能对另一个条目使用相同的键objectA?因为我做了一个小测试,我可以做到: public void test4WeakHashMap(WeakHashMap<B,

根据Java文档:

此类主要用于键对象,其equals方法使用==运算符测试对象标识。一旦丢弃此类键,就无法重新创建,因此无法在WeakHashMap中查找该键

这是否意味着如果我们在weakhashmap中使用objectA作为条目0的键,然后删除该条目
TestMapHash虚弱.remove(objectA)我们不能对另一个条目使用相同的键
objectA
?因为我做了一个小测试,我可以做到:

    public void test4WeakHashMap(WeakHashMap<B, String> testMapHashWeak) {
    B objectB = new B();
    String sTest = "hola";
    System.out.println("1st time - key&value inserted ->"+objectB+","+sTest);
    testMapHashWeak.put(objectB, sTest);
    System.out.println("Get element 1st time-> "+testMapHashWeak.get(objectB));
    testMapHashWeak.remove(objectB);
    //Insert 2nd time
    System.out.println("2st time - key&value inserted ->"+objectB+","+sTest);
    testMapHashWeak.put(objectB, sTest);        
    System.out.println("Get element 2nd time-> "+testMapHashWeak.get(objectB));
}
该句中的“丢弃”表示“关键对象不再是普通用途”,不再是活对象。您的
objectB
不是这种情况,它用于
test4WeakHashMap
方法的整个范围

来自同一文件:

WeakHashMap中的条目在其密钥不再正常使用时将自动删除。更准确地说,给定密钥映射的存在不会阻止垃圾收集器丢弃该密钥,也就是说,使其可终结、终结,然后回收。当一个键被丢弃时,它的条目将被有效地从映射中删除,因此这个类的行为与其他映射实现有所不同

请注意“被垃圾收集器丢弃”。因此,“从地图中删除”与“丢弃”不同。描述如下:

此类主要用于其 equals方法使用==运算符测试对象标识。一旦 这样的密钥将被丢弃—它永远无法重新创建,因此这是不可能的 在WeakHashMap中查找该键

意味着该类打算与键一起使用,在重新创建(创建完全相同的新实例)之后,当相互比较时,返回false。换句话说,此类键的每个新实例都是唯一的(仅当使用
equals()
与自身进行比较时返回true,当与任何其他实例/对象进行比较时返回false),例如
String
不是此类类,而
object
是:

WeakHashMap testMapHashWeak = new WeakHashMap<Object, String>();

String value1 = "Hola1!";
String value2 = "Hola2!";

String key1 = new String("key");
String key2 = new String("key");

assert key1 != key2; // Keys are different objects...
assert key1.equals(key2); // but are equal to each other

testMapHashWeak.put(key1, value1);
testMapHashWeak.put(key2, value2);

// value2 instead of value1!
System.out.println("Get using key1 (expected Hola1): "+testMapHashWeak.get(key1));
// value2
System.out.println("Get using key2 (expected Hola2): "+testMapHashWeak.get(key2));

Object key3 = new Object();
Object key4 = new Object();

assert key3 != key4; // Keys are different objects...
assert !key3.equals(key4); // and are not equal to each other

testMapHashWeak.put(key3, value1);
testMapHashWeak.put(key4, value2);

// value2 instead of value1!
System.out.println("Get using key3 (expected Hola1):"+testMapHashWeak.get(key3)); // value1!
// value2
System.out.println("Get using key4 (expected Hola2):"+testMapHashWeak.get(key4));
WeakHashMap testmaphhashweak=newweakhashmap();
字符串值1=“Hola1!”;
字符串值2=“Hola2!”;
字符串键1=新字符串(“键”);
字符串键2=新字符串(“键”);
断言键1!=键2;//关键点是不同的对象。。。
断言key1.equals(key2);//但它们是平等的
testmaphhashweak.put(键1,值1);
testmaphhashweak.put(键2,值2);
//value2而不是value1!
System.out.println(“使用key1获取(预期为Hola1):”+testmaphhashweak.Get(key1));
//价值2
System.out.println(“使用key2获取(预期为Hola2):”+testmaphhashweak.Get(key2));
对象键3=新对象();
对象键4=新对象();
断言键3!=键4;//关键点是不同的对象。。。
断言!键3.等于(键4);//两者并不相等
testmaphhashweak.put(键3,值1);
testMapHashWeak.put(键4,值2);
//value2而不是value1!
System.out.println(“使用key3获取(预期为Hola1):”+testmaphhashweak.Get(key3));//价值1!
//价值2
System.out.println(“使用key4获取(预期为Hola2):”+testmaphhashweak.Get(key4));

WeakHashMap
是具有弱密钥的Map的实现。所以在密钥被垃圾收集之后,map中的整个条目(key,value)都将消失。然后这里的关键词是“之后”,意思是不早一点。因此,在键被标记为“被GC删除”之前,映射将包含不可能获得的键值条目。在第一个基于字符串键的示例中,可以使用不同的键获取值,但无法预测值是否存在(可能已经是GCd)。在第二个例子中,无论如何你都不能。你的陈述是正确的,但你的例子不是。问题在于,包含字符串常量
“key”
的key1和key2是同一个实例(使用断言很好,在启用断言的情况下运行代码更好)。Java使用相同的对象实例来表示编译时常量字符串。将其中一个替换为
新字符串(“键”)
将创建所需的情况,即不同的字符串实例相等。尽管原始代码已损坏,但编辑被拒绝;我无法理解原因,因为我建议的修复方案保持了原意。然而:除了第一个断言失败之外,创建对象key3和key4之后的断言肯定应该引用它们,而不是再次引用key1和key2。看来,只有原始海报才有可能修复该代码。
WeakHashMap testMapHashWeak = new WeakHashMap<Object, String>();

String value1 = "Hola1!";
String value2 = "Hola2!";

String key1 = new String("key");
String key2 = new String("key");

assert key1 != key2; // Keys are different objects...
assert key1.equals(key2); // but are equal to each other

testMapHashWeak.put(key1, value1);
testMapHashWeak.put(key2, value2);

// value2 instead of value1!
System.out.println("Get using key1 (expected Hola1): "+testMapHashWeak.get(key1));
// value2
System.out.println("Get using key2 (expected Hola2): "+testMapHashWeak.get(key2));

Object key3 = new Object();
Object key4 = new Object();

assert key3 != key4; // Keys are different objects...
assert !key3.equals(key4); // and are not equal to each other

testMapHashWeak.put(key3, value1);
testMapHashWeak.put(key4, value2);

// value2 instead of value1!
System.out.println("Get using key3 (expected Hola1):"+testMapHashWeak.get(key3)); // value1!
// value2
System.out.println("Get using key4 (expected Hola2):"+testMapHashWeak.get(key4));