HashMap的hash位运算和扩容

本文深入解析HashMap的内部实现,包括其初始和扩容时数组长度的选择,以及如何通过位运算快速定位元素。当链表长度超过阈值时,HashMap会将链表转换为红黑树以优化查找效率。此外,还探讨了扩容过程中的元素迁移策略,防止链环死锁,确保数据结构的稳定性。
摘要由CSDN通过智能技术生成

HashMap

1.7(数组+链表)

1.数组长度:2的n次方,初始化长度不够会计算大于并最接近自定义长度的2的n次方的数值,例如3=>22, 11=>24, 12=>24, 17=>25
2.定位数组下标:时间复杂度O(n),通过hash位运算取余([key的hash] &[ 数组计算后的长度(2^n)-1])定位到数组下标位置(O(1)),可能会有hash冲突,冲突的hash使用链表保存(O(n))
ps:位运算为什么是要2n-1,是因为2n的二进制数只有一个1,其它都是0,例如16(0000 0000 0001 0000),导致与运算后的结果只有两种
(0000 0000 0001 0000=>16,0000 0000 0000 0000=>0),导致数据空出太多空间,而且超出最大下标,所以-1保证低位 都是1,高位都是0(0000 0000 0000 1111=>15),那不管与运算任何值,高位都是0,低位01之间随机,那不就是0~15之间了吗(牛逼)
3.数组扩容:扩容的阀值限定为数组长度*0.75(0.75是空间与时间的折中值),扩容的长度也是2^n(创建新数组),扩容是把旧数组的值移到新的数组,那就要重新算hash,扩容后的数组中的链表顺序会倒过来,具体可以查看源码,简单来讲就是,1,先把头部移到新数组的槽位,2,然后再把下个节点的尾部指针指向新数组的对应槽位上的节点(上个操作1所移动的那个节点),3,最后就是把新数组的下标指针指向2所在的节点,那就相当于原本新数组下标指向是2的变成了3,2就变成了3的下一个节点
ps:由于线程是不安全的,倒序会很容易形成闭环,那就是无法在往这个链表上put数据了

>1.7(数组+链表+红黑树

1.数组长度:同上
2.定位数据下标:同上, hash冲突后,当链表长度大于8(TREEIFY_THRESHOLD)时转成红黑树(前提要数组容量>=64(MIN_TREEIFY_CAPACITY),<64就扩容)
在这里插入图片描述
在这里插入图片描述

3.数组扩容:高低位转移拆分方式,避免链环死锁

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值