public static void main(String[] args) {
IdentityHashMap<Integer, Object> m1 = new IdentityHashMap<Integer, Object>();
Integer ONE = 1;
Integer TWO = 2;
Integer OTHER_ONE = new Integer(1);
Integer OTHER_TWO = new Integer(2);
m1.put(ONE, new Object());
m1.put(TWO, new Object());
System.out.println(m1.keySet()); // [1, 2]
m1.remove(OTHER_ONE); // Does not remove
System.out.println(m1.keySet()); // [1, 2]
m1.remove(ONE); // Does remove
System.out.println(m1.keySet()); // [2]
m1.keySet().removeAll(Arrays.asList(OTHER_TWO)); // ...
System.out.println(m1.keySet()); // [] WHAT?
}
我在源代码中找到了答案(见下文),但我不知道最终的原因。这是一个错误吗?
答案 0 :(得分:1)
我在java 1.7.0_11
中找到了这个源代码 public boolean removeAll(Collection<?> c) {
boolean modified = false;
for (Iterator<K> i = iterator(); i.hasNext(); ) {
if (c.contains(i.next())) {
i.remove();
modified = true;
}
}
return modified;
}
它正在使用c.contains(),因此行为取决于集合类。我从javadoc中无法理解。
我发现这是6年前报道的一个错误,但仍未解决! http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6588783
答案 1 :(得分:-1)
试试这个。它将说明发生了什么。
System.out.println(OTHER_ONE == ONE);
System.out.println(Arrays.asList(OTHER_ONE).contains( ONE));
OTHER_ONE是堆内存中的对象。 ONE不是对象,因此它驻留在常量池内存中。
如果使用new keyword
创建包装器对象,则只会将其转到堆内存,否则它将保存在常量池中。