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

Object.hashCode not descriminate enough.

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Cannot Reproduce
    • Icon: P4 P4
    • None
    • 1.1.6
    • core-libs
    • x86
    • windows_nt



      Name: dbT83986 Date: 02/15/99


      The real problem is that Classes are being stored in a HashMap container, and when the fully qualified Class name is hashed,
      unique names result in the same hash code.

      A simple example of this is:

      public class Badhash
      {
      public static void main( String[] args )
      {
      String a = "CybTestClassA";
      String b = "CybTestClassB";
      String c = "CybTestClassC";
      String d = "CybTestClassD";
      String e = "suhs.CybTestClassA";
      String f = "suhs.CybTestClassB";
      String g = "suhs.CybTestClassC";
      String h = "suhs.CybTestClassD";

      System.out.println("Hashcode value for " + a + ": " + a.hashCode());
      System.out.println("Hashcode value for " + b + ": " + b.hashCode());
      System.out.println("Hashcode value for " + c + ": " + c.hashCode());
      System.out.println("Hashcode value for " + d + ": " + d.hashCode());
      System.out.println("Hashcode value for " + e + ": " + e.hashCode());
      System.out.println("Hashcode value for " + f + ": " + f.hashCode());
      System.out.println("Hashcode value for " + g + ": " + g.hashCode());
      System.out.println("Hashcode value for " + h + ": " + h.hashCode());
      }
      }

      Gives output:

      C:\Java>java Badhash
      Hashcode value for CybTestClassA: -424829519
      Hashcode value for CybTestClassB: -424829518
      Hashcode value for CybTestClassC: -424829517
      Hashcode value for CybTestClassD: -424829516
      Hashcode value for suhs.CybTestClassA: 396812414
      Hashcode value for suhs.CybTestClassB: 396812414
      Hashcode value for suhs.CybTestClassC: 396812414
      Hashcode value for suhs.CybTestClassD: 396812414

      Obviously the last 4 should each be unique!

      A more specific example where the class name is used to hash:
      WITH the package keyword:

      package suhs;

      public class Suhs
      {
      public static void main( String[] args )
      {
      CybTestClassA a = new CybTestClassA();
      CybTestClassB b = new CybTestClassB();
      CybTestClassC c = new CybTestClassC();
      CybTestClassAA aa = new CybTestClassAA();
      CybTestClassBB bb = new CybTestClassBB();
      CybTestClassCC cc = new CybTestClassCC();
      CybTestClassAAA aaa = new CybTestClassAAA();
      CybTestClassBBB bbb = new CybTestClassBBB();
      CybTestClassCCC ccc = new CybTestClassCCC();
      CybTestClassAAAA aaaa = new CybTestClassAAAA();
      CybTestClassBBBB bbbb = new CybTestClassBBBB();
      CybTestClassCCCC cccc = new CybTestClassCCCC();
      CybTestClassAAAAA aaaaa = new CybTestClassAAAAA();
      CybTestClassBBBBB bbbbb = new CybTestClassBBBBB();
      CybTestClassCCCCC ccccc = new CybTestClassCCCCC();
      CybTestClassAAAAAA aaaaaa = new CybTestClassAAAAAA();
      CybTestClassBBBBBB bbbbbb = new CybTestClassBBBBBB();
      CybTestClassCCCCCC cccccc = new CybTestClassCCCCCC();
      CybTestClassAAAAAAA aaaaaaa = new CybTestClassAAAAAAA();
      CybTestClassBBBBBBB bbbbbbb = new CybTestClassBBBBBBB();
      CybTestClassCCCCCCC ccccccc = new CybTestClassCCCCCCC();
      CybTestClassAAAAAAAA aaaaaaaa = new CybTestClassAAAAAAAA();
      CybTestClassBBBBBBBB bbbbbbbb = new CybTestClassBBBBBBBB();
      CybTestClassCCCCCCCC cccccccc = new CybTestClassCCCCCCCC();

      System.out.println("Hashcode value for '" + a.getClass().getName() + "':" + a.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + b.getClass().getName() + "':" + b.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + c.getClass().getName() + "':" + c.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + aa.getClass().getName() + "':" + aa.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + bb.getClass().getName() + "':" + bb.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + cc.getClass().getName() + "':" + cc.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + aaa.getClass().getName() + "':" + aaa.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + bbb.getClass().getName() + "':" + bbb.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + ccc.getClass().getName() + "':" + ccc.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + aaaa.getClass().getName() + "':" + aaaa.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + bbbb.getClass().getName() + "':" + bbbb.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + cccc.getClass().getName() + "':" + cccc.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + aaaaa.getClass().getName() + "':" + aaaaa.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + bbbbb.getClass().getName() + "':" + bbbbb.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + ccccc.getClass().getName() + "':" + ccccc.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + aaaaaa.getClass().getName() + "':" + aaaaaa.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + bbbbbb.getClass().getName() + "':" + bbbbbb.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + cccccc.getClass().getName() + "':" + cccccc.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + aaaaaaa.getClass().getName() + "':" + aaaaaaa.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + bbbbbbb.getClass().getName() + "':" + bbbbbbb.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + ccccccc.getClass().getName() + "':" + ccccccc.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + aaaaaaaa.getClass().getName() + "':" + aaaaaaaa.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + bbbbbbbb.getClass().getName() + "':" + bbbbbbbb.getClass().getName().hashCode());
      System.out.println("Hashcode value for '" + cccccccc.getClass().getName() + "':" + cccccccc.getClass().getName().hashCode());
      }
      }

      class CybTestClassA {}
      class CybTestClassB {}
      class CybTestClassC {}

      class CybTestClassAA {}
      class CybTestClassBB {}
      class CybTestClassCC {}

      class CybTestClassAAA {}
      class CybTestClassBBB {}
      class CybTestClassCCC {}

      class CybTestClassAAAA {}
      class CybTestClassBBBB {}
      class CybTestClassCCCC {}

      class CybTestClassAAAAA {}
      class CybTestClassBBBBB {}
      class CybTestClassCCCCC {}

      class CybTestClassAAAAAA {}
      class CybTestClassBBBBBB {}
      class CybTestClassCCCCCC {}

      class CybTestClassAAAAAAA {}
      class CybTestClassBBBBBBB {}
      class CybTestClassCCCCCCC {}

      class CybTestClassAAAAAAAA {}
      class CybTestClassBBBBBBBB {}
      class CybTestClassCCCCCCCC {}

      Gives output:

      C:\Java>java suhs.Suhs
      Hashcode value for 'suhs.CybTestClassA':396812414
      Hashcode value for 'suhs.CybTestClassB':396812414
      Hashcode value for 'suhs.CybTestClassC':396812414
      Hashcode value for 'suhs.CybTestClassAA':-1704184973
      Hashcode value for 'suhs.CybTestClassBB':-1704184972
      Hashcode value for 'suhs.CybTestClassCC':-1704184971
      Hashcode value for 'suhs.CybTestClassAAA':-1704184973
      Hashcode value for 'suhs.CybTestClassBBB':-1704184972
      Hashcode value for 'suhs.CybTestClassCCC':-1704184971
      Hashcode value for 'suhs.CybTestClassAAAA':-2038704442
      Hashcode value for 'suhs.CybTestClassBBBB':-2038704402
      Hashcode value for 'suhs.CybTestClassCCCC':-2038704362
      Hashcode value for 'suhs.CybTestClassAAAAA':-2038704442
      Hashcode value for 'suhs.CybTestClassBBBBB':-2038704402
      Hashcode value for 'suhs.CybTestClassCCCCC':-2038704362
      Hashcode value for 'suhs.CybTestClassAAAAAA':2094905451
      Hashcode value for 'suhs.CybTestClassBBBBBB':2094907012
      Hashcode value for 'suhs.CybTestClassCCCCCC':2094908573
      Hashcode value for 'suhs.CybTestClassAAAAAAA':1054564892
      Hashcode value for 'suhs.CybTestClassBBBBBBB':1054564932
      Hashcode value for 'suhs.CybTestClassCCCCCCC':1054564972
      Hashcode value for 'suhs.CybTestClassAAAAAAAA':-1821642107
      Hashcode value for 'suhs.CybTestClassBBBBBBBB':-1821640546
      Hashcode value for 'suhs.CybTestClassCCCCCCCC':-1821638985

      And the same thing without the package keyword gives output:

      C:\Java>java Suhs
      Hashcode value for 'CybTestClassA':-424829519
      Hashcode value for 'CybTestClassB':-424829518
      Hashcode value for 'CybTestClassC':-424829517
      Hashcode value for 'CybTestClassAA':1461177046
      Hashcode value for 'CybTestClassBB':1461177084
      Hashcode value for 'CybTestClassCC':1461177122
      Hashcode value for 'CybTestClassAAA':-1771024081
      Hashcode value for 'CybTestClassBBB':-1771022674
      Hashcode value for 'CybTestClassCCC':-1771021267
      Hashcode value for 'CybTestClassAAAA':989624285
      Hashcode value for 'CybTestClassBBBB':989624325
      Hashcode value for 'CybTestClassCCCC':989624365
      Hashcode value for 'CybTestClassAAAAA':-59358484
      Hashcode value for 'CybTestClassBBBBB':-59356923
      Hashcode value for 'CybTestClassCCCCC':-59355362
      Hashcode value for 'CybTestClassAAAAAA':-59358484
      Hashcode value for 'CybTestClassBBBBBB':-59356923
      Hashcode value for 'CybTestClassCCCCCC':-59355362
      Hashcode value for 'CybTestClassAAAAAAA':1979986485
      Hashcode value for 'CybTestClassBBBBBBB':1980047365
      Hashcode value for 'CybTestClassCCCCCCC':1980108245
      Hashcode value for 'CybTestClassAAAAAAAA':1979986485
      Hashcode value for 'CybTestClassBBBBBBBB':1980047365
      Hashcode value for 'CybTestClassCCCCCCCC':1980108245

      The hashcodes are different for each run as expected, but the
      PATTERN of hashcode likeness is unexpectedly different (actually, any likeness is unexpected).
      In the non-package run, the same hashcodes are seen near the
      end of the run (
      the 4 and 5 'A' are the same, the 6 and 7 'A' are the same,
      the 4 and 5 'B' are the same, the 6 and 7 'B' are the same,
      the 4 and 5 'C' are the same, the 6 and 7 'C' are the same).

      In the package run, the same hashcodes are seen near the
      beginning of the run (
      the 'A', 'B', 'C' are the same,
      the 2 and 3 'A' are the same, the 4 and 5 'A' are the same,
      the 2 and 3 'B' are the same, the 4 and 5 'B' are the same,
      the 2 and 3 'C' are the same, the 4 and 5 'C' are the same).
      (Review ID: 35065)
      ======================================================================

            jjb Josh Bloch
            dblairsunw Dave Blair (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: