Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8178355

IdentityHashMap uses identity-based comparison for values everywhere except remove(K,V) and replace(K,V,V)

XMLWordPrintable

    • b23
    • generic
    • generic
    • Verified

      FULL PRODUCT VERSION :
      java version "1.8.0_121"
      Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
      Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Darwin localhost 16.4.0 Darwin Kernel Version 16.4.0: Thu Dec 22 22:53:21 PST 2016; root:xnu-3789.41.3~3/RELEASE_X86_64 x86_64 i386 MacBookPro11,4 Darwin

      A DESCRIPTION OF THE PROBLEM :
      IdentityHashMap's documentation says the map uses identity-based comparison for keys and values. Indeed, #keySet and #values() return identity-based collections. #entrySet returns collection that compares entries by key and value identity too.

      However, the #remove(K,V) and #replace(K,V,V) methods inherited from Map (implemented with default methods in Map interface), compare values by equality rather than identity.

      This can be shown with the code:

      -------------
      IdentityHashMap map = new IdentityHashMap();
      map.put("key", new String("value"));
      System.out.println(map.remove("key", new String("value"))); // expected "false"
      -------------

      REGRESSION. Last worked in version 7u80

      ADDITIONAL REGRESSION INFORMATION:
      In Java 7 there was no public method in IdentityHashMap that compared values by equality.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      IdentityHashMap map = new IdentityHashMap();
      map.put("key", new String("value"));
      System.out.println(map.remove("key", new String("value")));

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      "false" should be printed, map unchanged
      ACTUAL -
      "true" printed, map emptied

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.util.IdentityHashMap;
      public class A {
          public static void main(String[] args) {
              IdentityHashMap map = new IdentityHashMap();
              map.put("key", new String("value"));
              System.out.println(map.remove("key", new String("value")));
          }
      }
      ---------- END SOURCE ----------

            smarks Stuart Marks
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            9 Start watching this issue

              Created:
              Updated:
              Resolved: