HashMap

个人补充:

参考:

HashMap如何计算Entry在桶中的下标? - 简书 (jianshu.com)

(135条消息) java基础--04--集合框架--02--HashMap初始化/定位桶位置/扩容源码分析--jdk1.8_na_tion的专栏-CSDN博客

1、定位桶位置

增加、删除、查找键值对,定位到哈希桶数组的位置都是关键的第一步。
HashMap处理逻辑为:先是通过扰动函数hash(Object key)处理key的hashCode而得到其hash 值,然后通过 hash&(capacity-1)判断当前元素存放的位置。

    static final int hash(Object key) {
        int h;
        //^ (h >>> 16)为扰动函数,作用见见2.3分析-(3)
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

HashMap中的代码如下:

int hash = hash(key);
int i = indexFor(hash, table.length);

分析
(1)key.hashCode()函数调用的是key键值类型自带的哈希函数public native int hashCode()返回的int类型。如果直接拿散列值做数组下标,那么索引范围就是‑2147483648到2147483648,前后加起来大概40亿的映射空间,但桶数组默认的初始容量最大才16,这就说明hashCode()返回的散列值是不能直接用来访问,需要映射到桶的容量空间(%、&)。

(2)桶下标计算公式是hash&(capacity-1)。之所以不使用hash % capacity方式取模,是因为HashMap中规定了哈希表长度为2 的幂,在这种情况下,位与运算更快, resize() 扩容时也可以更高效地重新计算桶下标【hash&(capacity-1)计算方式,可以使新老桶位置之间存在一定关系】。

(3)扰动函数作用

        (a)桶下标计算如果直接使用key.hashCode()&(capacity-1),因初始时capacity值较小,所以总会截取最后几位,碰撞会比较严重。比如capacity=16,capacity-1=15

  0000 0000 0000 0000 0000 0000 0000 1111
& 1111 1111 1111 1111 1111 0000 1110 1010
--------------------------------------------
  0000 0000 0000 0000 0000 0000 0000 1010
        (b)这时候扰动函数的作用就体现出来了:右位移16位,正好是32的一半,自己的高半区与低半区做异或,就是为了混合原始哈希码的高位与低位,以此来加大低位随机性。而混合后的低位参杂了高位部分特征,高位信息也参入了寻址计算(进行扰动)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值