HashMap的resize()过程简述版本

初始默认大小为16,默认负载阈值0.75;每次扩容2倍;

 

1. 如果oldCap已经超出最大容量。

将Integer.MAX_VALUE赋给阈值,返回旧表;

 

2. 如果oldCap以及oldCap*2是介于16和最大容量之间(多落在这个分支),oldCap*2得到新容量,oldThr*2得到新阈值;

 

3. 如果oldCap==0并且oldThr>0,那么oldThr直接赋给newCap;

这个比较有意思,涉及到HashMap的几种初始化,深入说一下。

(1)如果使用public HashMap()初始化表,oldCap为0,oldThr也为0,会走到下一个分支(第4点);

(2)如果使用public HashMap(int initialCapacity)初始化,会进一步调用public HashMap(int initialCapacity, float loadFactor),该构造方法将threshold赋值为大于等于initialCapacity的2的幂,也就出现了第3点的分支(oldCap只跟表有关系,与initialCapacity无关)。

(3)如果落在这个分支,newCap获得了threshold,在跳出分支之后还有单独的代码对threshold赋值,赋值为newCap*loadFactor。

 

4. 如果oldCap==0并且oldThr==0,那么newCap赋值16,newThr赋值16*0.75;

 

5. 扩容结束之后,会对表rehash,树的部分略过,链表的部分就是根据hash高位值划分为两个子链表,一个连接在原来的位置,一个连接到j+oldCap的位置。

jdk1.7之前的扩容操作,如果涉及到多线程可能会出现链表循环的问题,原因是1.7版本采用遍历+头插的方法进行rehash,1.8则直接连接在两个子链表的末尾,也就避免了这个问题。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值