HashMap扩容resize流程

本文详细探讨了HashMap在Java中的扩容过程,包括初始化时的默认容量和阈值设置,以及在size超过阈值或特定条件下的扩容策略。在扩容时,HashMap会按照一定的规则计算新容量和阈值,并创建新的Node数组进行数据迁移。对于链表过长的情况,HashMap会转换为红黑树以优化查找效率。整个过程确保了数据的正确性和性能。
摘要由CSDN通过智能技术生成

resize函数触发时机:

1.初始化HashMap的默认扩容一个cap为16 threshold为12的Node<K, V>[] newTab

2.当hashMap的size>threshold的时候再次扩容,扩容为16*2的cap,threshold*2的Node<K, V>[] newTab

3.当table中Node链表大于8且tab.length小于64的时候,hash再次double扩容

下面直接上流程图

 第一阶段:主要为计算出新的newCap(扩容后的容量)和newThr(扩容后阈值)

第二阶段: 根据newCap和newThr组装出新的newTab

接下来直接上源码

若之前的数据为空,默认初始化一个容量为16 阈值为12

newCap = DEFAULT_INITIAL_CAPACITY; /** 默认【表容量】为16(1 << 4) */
newThr = (int) (DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY); 

若扩容两倍之后小于最大长度且大于等于初始化的tab(16),cap和thr直接*2

else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY && oldCap >= DEFAULT_INITIAL_CAPACITY) {
    // eg6: newCap=32, newThr=24
    newThr = oldThr << 1;
}

若oldCap已经达到最大值,直接将最大的tab返回

从以上源码可以看出,第一部分主要是为计算出newCap和newThr

 第二阶段:主要是根据newCap和newThr构造出新的newTab

1.组装出一个新的newTab

2.查询oldTab中是否还存在数据,存在数据的需要迁移到newTab

3.若oldTab下标只有一个链表Node,直接根据该Node的hash直接在newTab中重新定位存储

newTab[e.hash & (newCap - 1)] = e;

4.如果是树节点,直接维护到TreeNode

5.

if ((e.hash & oldCap) == 0)

true:该e节点(Node)不需要重新定位

loHead:数组中第一个Node

loTail:该下标中最后一个Node

不需要重新定位:

newTab[j] = loHead;

false:该e节点(Node)需要根据newTab重新定位

hiHead:该下标中第一个需要重新定位的Node

hiTail:该下标中最后一个需要重新定位的Node

需要重新定位:

newTab[j + oldCap] = hiHead;

6.e.next再次回到第五步判读是否需要重新定位,再次定位在新的newTab,直到循环结束,oldTab数据迁移完毕!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值