您的位置:首页 > 编程语言 > Java开发

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

2017-05-05 22:37 393 查看

what?

我们先看一端代码。

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

Map<String, Object> map = new TreeMap<String, Object>();

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hashmap jdk