Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Incorrect value returned by IdentityHashMap - Why?

Tags:

java

hashmap

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?

like image 547
Sachin Sachdeva Avatar asked Jun 21 '17 09:06

Sachin Sachdeva


2 Answers

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.

like image 172
Pallavi Sonal Avatar answered Nov 16 '22 04:11

Pallavi Sonal


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!

like image 29
GhostCat Avatar answered Nov 16 '22 05:11

GhostCat