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