java hashmap扩容大小_阅读 JDK 8 源码:HashMap 扩容总结及图解

在 Java8 中,HashMap 由数组+链表+红黑树组成的。扩容时,数组容量翻倍,数组中每一个桶中的多个节点(链结构或树结构)都需要 rehash 迁移到新的数组中去。

本文通过阅读 HashMap 的 resize 方法了解其扩容原理,对桶节点的迁移算法进行单元测试,画图以方便理解。

1. 扩容的时机HashMap 中 put 入第一个元素,初始化数组 table。

HashMap 中的元素数量大于阈值 threshold。threshold = capacity * load factor。

当 size > threshold 时,触发 rehash。

2. 扩容的源码

HashMap 中的 resize 方法主要包含两部分逻辑:初始化数组 table,并设置阈值。

数组容量翻倍,将元素迁移到新数组。/**

* Initializes or doubles table size. If null, allocates in

* accord with initial capacity target held in field threshold.

* Otherwise, because we are using power-of-two expansion, the

* elements from each bin must either stay at same index, or move

* with a power of two offset in the new table.

*

* @return the table

*/

final Node[] resize() {

Node[] oldTab = table;

int oldCap = (oldTab == null) ? 0 : oldTab.length;

int oldThr = threshold;

int newCap, newThr = 0;

if (oldCap > 0) { // 第一次进来,table为null,oldCap为0,不会进入这里

if (oldCap >= MAXIMUM_CAPACITY) { // 扩容前的数组大小如果已经达到最大(2^30)了

threshold = Integer.MAX_VALUE; // 取整型最大值(2^31-1),这样以后就不会扩容了

return oldTab;

}

else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY && // oldCap翻倍得到newCap

oldCap >= DEFAULT_INITIAL_CAPACITY)

newThr = oldThr << 1; // double threshold

}

else if (oldThr > 0) // initial capacity was placed in threshold // 第一次进来,如果手动设置了初始容量initialCapacity,这里为true,则将threshold作为初始容量

newCap = oldThr;

else { // zero initial threshold signifies using defaults // 如果没有手动设置initialCapacity,则设为默认值16

newCap = DEFAULT_INITIAL_CAPACITY;

newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);

}

if (newThr == 0) { // 第一次进来,这里必为true,重新计算 threshold = capacity * Load factor

float ft = (float)newCap * loadFactor;

newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?

(int)ft : Integer.MAX_VALUE);

}

threshold = newThr;

@SuppressWarnings({"rawtypes","unchecked"})

Node[] newTab = (Node[])new Node[newCap];

table = newTab;

if (o

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值