HashMap底层
put 的时候是key,value
底层实现是 put方法调用putVal(hash(key), key, value, false, true);
其中 hash(key)是计算index的
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
key.hashCode()与key.hashCode()右移16位后做异或运算
key.hashCode() 是关键
位移运算是为了解决 取模效率问题,至于为啥是2的n 次幂,原因是 移除去的n位就是余数
下标直接是key.hashCode()&(length-1),则只有hashCode()的低位参与运算(因为hashCode()是32位的,而length-1一般不大,比如容量16,16-1=15,15二进制就是1111,换成32位的话,高位就全是0了,根据&运算规则1&1=1,其他情况都是0,所以hashCode()高位没参与运算了),如果低位不变,只是高位变,key.hashCode()&(length-1)值还是一样,那么就冲突了。
key.hashCode()右移16位就是高位变成了低位,原来高位全补0,,然后做运算,实际就是原来的hashCode()值的高位与低位做运算,这就解决了低位不变高位无论变与不变仍冲突的问题,现在无论高位低位哪个变,最终hash值都会变。
这里用的是运算,看下面的运算规则,很明显,结果相同概率是2/4,而其他两个运算结果相同概率都是3/4,我们目的是尽量让高位低位变化产生的值不一样,所以自然就选^了。
位与(&) : 0 & 0 = 0 0 & 1 = 0 1 & 0 = 0 1 & 1 =1 ;
位异或(^): 0 ^ 0 = 0 0 ^ 1 = 1 1 ^ 0 = 1 1 ^ 1 = 0
按位或(|): 0 | 0 = 0 0 | 1 = 1 1 | 0 = 1 1 | 1 = 1
有些是参考别人的,有问题大家提出来一起进步。
原文链接:https://blog.csdn.net/meser88/article/details/104823570/
public native int hashCode();