To my understanding, the following code should print false
as it is doing identity
based comparison.
However, when I run the following code it is printing true
:
public class Test1 {
public static void main(String[] args) {
IdentityHashMap m = new IdentityHashMap();
m.put("A", new String("B"));
System.out.println(m.remove("A", new String("B")));
}
}
Can some one help me understand why this behaving like this?
You have actually hit a bug in JDK, see JDK-8178355. IdentityHashMap
does not have custom implementation of the remove(K,V)
method added to Map
via default method, which is causing this issue.
You put "A", new "B"
You remove "A", new "B"
So, yes, your assumption that this IdentityHashMap should not remove that value looks correct.
But you are using the remove(key, value)
method from the base AbstractMap - which is not overriden by this specific subclass!
So, although the javadoc says:
This class implements the Map interface with a hash table, using reference-equality in place of object-equality when comparing keys (and values).
The (and values) part is (probably) implemented only for inserting key/value pairs.
So, the important part again comes from the javadoc:
This class is not a general-purpose Map implementation! While this class implements the Map interface, it intentionally violates Map's general contract, which mandates the use of the equals method when comparing objects. This class is designed for use only in the rare cases wherein reference-equality semantics are required.
My (probably opinionated) take-away: this class is a very special thing. It has a very clear, and narrow purpose. And you found an example where it falls apart. (which I don't find surprising: when you "change" semantics but decide to re-use existing code, it is almost inevitable to run into such kind of inconsistencies).
It could be seen as bug; and as the other answer confirms: it is a bug!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With