hash方法
这一节主要老看看哈希算法,代码如下:
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
对key做hashCode运算得到h,然后再对h无符号右移16位再与h做异或运算。h无符号右移16位,则结果是高16位全为0。那么和h运算的结果中,高16位取决于h,低16位其实就是h的高16和低16异或的结果。
为了更好的说明,假设
x = (h >>> 16)
y = h ^ x
这里得到的x的低16位,就是h的高16位。
y的低16位其实就是h的低16位和h的高16位运算的结果。
无符号右移16再异或的好处是什么呢?
后续环节还有位运算,但是用低16位进行运算,如果不把hash值的高16位和低16位进行运算,就会导致后面通过hash值找到数组index的时候,只有低16位参与了运算。在hash函数里面,把高16位和低16位异或运算,可以保证,在hash值的低16位里面,可以同时保留高16位和低16位的特征。
定位元素在数组中的index时,同时将高16位和低16位的特征纳入运算,可以降低hash冲突的概率,如果直接用hash值的低16位去运算,可能会导致一定的hash冲突。
哈希冲突
很多key,可能值不同,但是hash值可能是相同的,或者是hash值不同,但是到数组的index相同,那么都会出现hash冲突
总结
无符号右移运算符(>>>)和右移运算符(>>)的主要区别在于负数的计算。前者右移高位补0,后者高位补1,移多少位补多少位。
异或运算相同为0,不同为1。