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
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);
}