HashMap引起的事故:jdk1.7和jdk1.8下的hash函数的不同

what?

我们先看一端代码。

JsonMapper jsonMapper = JsonMapper.nonDefaultMapper();
HashSet objects = Sets.newHashSet();
for (int i = 0; i < 1000; i++) {

    Map map = new TreeMap();

    map.put("score", -1.469587024258E12);
    map.put("feedId", "133977005581429120");
    map.put("type", 3);
    map.put("otherFeedId", "");
    String s = jsonMapper.toJson(map);
    objects.add(s);

    try {
        Thread.sleep(1);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

输出 使用jdk1.7出书结果为
{“feedId”:”133977005581429120”,”score”:-1.469587024258E12,”otherFeedId”:”“,”type”:3}
使用jdk1.8
{“score”:-1.469587024258E12,”feedId”:”133977005581429120”,”otherFeedId”:”“,”type”:3}

why?

jdk中hash函数的源码的源码分析,在jdk1.7中。

final int hash(Object k) {
int h = hashSeed;
if (0 != h && k instanceof String) {
return sun.misc.Hashing.stringHash32((String) k);
}
h ^= k.hashCode();
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}

在jdk1.8中:

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

危害

不用这个字符串做唯一去重,比如Set中,数据库中的唯一键等

解决问题:

使用TreeSet代替HashSet,或者直接拼成string

你可能感兴趣的:(core,java,故障分析)