Frage

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?

War es hilfreich?

Lösung

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

Andere Tipps

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top