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

xiaoxiao2021-02-28  82

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

转载请注明原文地址: https://www.6miu.com/read-43216.html

最新回复(0)