Search code examples
javajava-7java-5

what has change in Java 7 for HashMap from Java 5


I'm not a java expert, just experience the change in the output of following program on Java 5 and Java 7. Could anyone has an idea what has change in Java 7 for HashMap implementation?

import java.util.HashMap;
import java.util.Map;

public class HashMapDemo {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("1", "111");
        map.put("a", "aaa");
        map.put("A", "AAA");

        map.put("D", "DDD");
        map.put("d", "ddd");
        map.put("0", "000");

        map.put("B", "BBB");
        map.put("b", "bbb");
        map.put("2", "222");

        for(Map.Entry<String, String> entry : map.entrySet()){
            System.out.println(entry.getKey()+ "  "+entry.getValue());
        }
    }
}

Output on Java 7

D  DDD
2  222
d  ddd
1  111
0  000
b  bbb
A  AAA
B  BBB
a  aaa

The Output on Java 5

0  000
1  111
a  aaa
A  AAA
B  BBB
b  bbb
2  222
D  DDD
d  ddd

Solution

  • The hashing algorithm changed. This means that you cannot rely on the iteration order of java.util.HashMap. This shouldn't come as a surprise, the JDK never gave any such guarantees in the first place. If order is important to you, use TreeMap or LinkedHashMap.

    JDK5 HashMap:

    static final int hash(Object key) {
       int h;
       return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }
    

    JDK7 HashMap:

    final int hash(Object k) {
      int h = hashSeed;
      if (0 != h && k instanceof String) {
         return sun.misc.Hashing.stringHash32((String) k);
      }
    
      h ^= k.hashCode();
      // This function ensures that hashCodes that differ only by
      // constant multiples at each bit position have a bounded
      // number of collisions (approximately 8 at default load factor).
      h ^= (h >>> 20) ^ (h >>> 12);
      return h ^ (h >>> 7) ^ (h >>> 4);
    }