hash()方法亦或前16位原因

    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

    public native int hashCode();
位运算符有三种,|,&,……,或,与,亦或。
a,b进行位运算,有4种可能 00,01,10,11
    a或b计算 结果为1的几率为3/4,0的几率为1/4 a与b计算 结果为0的几率为3/4,1的几率为1/4, a亦或b计算 结果为1的几率为1/2,0的几率为1/2
所以,进行亦或计算,得到的结果肯定更为平均,不会偏向0或者偏向1,更为散列。
右移16位进行亦或计算,我将其拆分为两部分,前16位的亦或运算,和后16位的亦或运算,
后16位的亦或运算,即原hashcode后16位与原hashcode前16位进行亦或计算,得出的结果,前16位和后16位都有参与其中,保证了
32位全部进行计算。
前16位的亦或运算,即原hasecode前16位与0000 0000 0000 0000进行亦或计算,结果只与前16位hashcode有关,同时亦或计算,保证
结果为0的几率为1/2,1的几率为1/2,也是平均的。
所以为什么是右移16位
也有一个原因是右移16位进行亦或计算的结果中,
(1)结果的后16位保证了hashcode32位全部参与计算,也保证了0,1平均,散列性
(2)结果的前16位保证hashcode前16位了0,1平均散列性,附带hashcode前16位参与计算。
(3) 16与16位数相同,利于计算,不需要补齐,移去位数数据
更多情况,hashmap只会用到前16位(临时数据一般不会这么大),所以(1)占主因。

--- 摘自https://blog.csdn.net/qq_42034205/article/details/90384772   评论区io.ke的内容

#java#
全部评论
JDK并没有直接使用Object的native方法返回的hashCode作为最终的哈希值,而是进行了二次加工。 使用key对应的hashCode与其hashCode右移16位的结果进行异或操作。此处,将高16位与低16位进行异或的操作称之为扰动函数,目的是将高位的特征融入到低位之中,降低哈希冲突的概率。
1 回复
分享
发布于 2022-03-28 15:20

相关推荐

2 3 评论
分享
牛客网
牛客企业服务