文章借鉴https://www.zhihu.com/question/20733617
HashMap的高深有一本分就在于key值的快速散列接下来贴出 1.7 和1.8的代码
1.8源码
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
1.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();
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
可以从源码中看到 所有的hash值都与自身进行了异或并且自身异位
原因大致将一下。。应为hash值是一个int类型的数据 大小在-2147483648到2147483648 看结果就知道map是无法存放这么大角标的数据
所有我们需要将hash值进行求余 当然求于比较简单
return h & (length-1);
关键点在于既然将hash值变小了 就很容易造成碰撞(求于之后就有两个hash值相等)这时候就需要扰动函数 函数来发挥功能了
这样做的目的就在于你求于的时候包含了高16位和第16位的特性 也就是说你所计算出来的hash值包含从而使得你的hash值更加不确定 来降低碰撞的概率