Question

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?
}

Reference here IdentityHashMap.keySet()

I found an answer in the source code (see below) but I don't know the ultimate reason. Is it a bug?

Was it helpful?

Solution

I found this source code from 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;
    }

It is using c.contains() so the behaviour depends on the collection class. I didn't understand that from the javadoc.

I found out it is a bug reported 6 years ago and still unresolved!! http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6588783

OTHER TIPS

Try this one. It will illustrate what happened.

  System.out.println(OTHER_ONE == ONE);
  System.out.println(Arrays.asList(OTHER_ONE).contains( ONE));

OTHER_ONE is the object that will in the heap memory. ONE is not an object so it resides in the constant pool memory.

if you create Wrapper Objects with new keyword then only it will go to heap memory otherwise it will saved in the constant pool.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top