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相关文章推荐
- Linux安装jdk1.7和tomcat9版本不匹配引起的错误
- 牛客网Java刷题知识点之HashMap的实现原理、HashMap的存储结构、HashMap在JDK1.6、JDK1.7、JDK1.8之间的差异以及带来的性能影响
- 【不做标题党,只做纯干货】HashMap在jdk1.7和1.8中的实现
- 一次HashMap多线程安全引起的事故
- HashMap的容量大小增长原理(JDK1.6/1.7/1.8)
- Java集合类框架学习 4.2 —— HashMap(JDK1.7)
- jdk 1.7 hashMap源码解读
- HashMap的put方法源码解析_JDK1.7
- JDK1.8的hashmap实现与JDK1.7的差别导致的一个问题
- HashMap源码解析(基于JDK1.7)
- Collection.removeAll 在 JDK 1.6 和 JDK 1.7 上不同的表现
- ConcurrentHashMap从jdk1.7到jdk1.8的变化
- jdk源码剖析四:JDK1.7升级1.8 HashMap原理的变化
- jdk1.6 的 HashMap 源码分析及1.7,1.8的主要更改
- ActiveMQ引起的JDK1.7 SSL错误
- jdk1.7 HashMap的实现原理
- String.intern() 方法__jdk1.6与jdk1.7的不同
- jdk 1.7 1.8 HashMap 源码分析
- dubbox部署到jdk1.7环境,启动:java.lang.NoSuchMethodError: java.util.concurrent.ConcurrentHashMap.keySet()
- jdk版本不同引起的问题分析