HashMap resize 扩容方法

HashMap的resize方法会在容量达到阈值时触发,通过扩容至原容量的2倍来重新分布元素。文章详细阐述了扩容条件、扩容过程,包括对现有元素的重新hash、设置新索引,以及针对不同数据结构(null、单个Entry节点、红黑树)的特殊处理。在扩容过程中,保证了数据的有序性和正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

扩容方法:判断当前容量是否大于最大容量,或者左移一位之后大于最大容量,或者是null的时候,对当前HashMap进行扩容

第一次进来的时候会对tab数组设置容量为16;

阈值设置为0.75*16

如果非空的时候,会对所有当前HashMap的所有数据都进行重新hash,设置索引,针对tab里面不通的数据(null,数组、一个Entry节点,红黑树)进行不同的处理,并放进扩容之后的HashMap中去。

final Node<K,V>[] resize() {

//获取当前HashMap的Entry数组

Node<K,V>[] oldTab = table;

//扩容之前的HashMap的容量

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

//扩容之前的HashMap的阈值

int oldThr = threshold;

//初始化新的容量阈值

int newCap, newThr = 0;

//这个是HashMap中存在数据的

if (oldCap > 0) {

//如果当前的容量大于或等于最大的容量

if (oldCap >= MAXIMUM_CAPACITY) {

//阈值设置为Integer的最大值

threshold = Integer.MAX_VALUE;

//返回 现在的HashMap

return oldTab;

//如果当前的容量左移一位小于最大的容量,切大于16 也就是初始化的容量

}else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&

oldCap >= DEFAULT_INITIAL_CAPACITY) {

newThr = oldThr << 1; // double threshold

}

}else if (oldThr > 0) { // initial capacity was placed in threshold

newCap = oldThr;

}else { // zero initial threshold signifies using defaults

newCap = DEFAULT_INITIAL_CAPACITY;

newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);

}

if (newThr == 0) {

float ft = (float)newCap * loadFactor;

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

(int)ft : Integer.MAX_VALUE);

}

threshold = newThr;

//第一次put值的时候 初始化 负载因子0.75 容量 16 阈值 12

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

Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap]; //初始化

//把初始化的Entry数组赋值给table

table = newTab;

//未扩容之前的Entry数组

if (oldTab != null) {

//循环未扩容之前的Entry数组

for (int j = 0; j < oldCap; ++j) {

//定义一个Node

Node<K,V> e;

//把当前J传递给定义的node数据e 进行判断

if ((e = oldTab[j]) != null) {

//清空oldTab[j]的数据

oldTab[j] = null;

//如果e的下一节点是null

if (e.next == null) {

//重新定义索引 并赋值给扩容之后的HashMap

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

//判断当前e是否属于树节点(红黑树)

}else if (e instanceof TreeNode) {

//进行split操作

((TreeNode<K, V>) e).split(this, newTab, j, oldCap);

}else { // preserve order

//低位头 低位尾

Node<K,V> loHead = null, loTail = null;

//高位头 高位尾

Node<K,V> hiHead = null, hiTail = null;

//next 下一节点

Node<K,V> next;

//下面一大串可以理解为把对应的数组数据给赋值给扩容之后的hashMap里面去

do {

next = e.next;

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

if (loTail == null){

loHead = e;

}else {

loTail.next = e;

}

loTail = e;

}else {

if (hiTail == null) {

hiHead = e;

}else{

hiTail.next = e;

}

hiTail = e;

}

} while ((e = next) != null);

if (loTail != null) {

loTail.next = null;

newTab[j] = loHead;

}

if (hiTail != null) {

hiTail.next = null;

newTab[j + oldCap] = hiHead;

}

}

}

}

}

return newTab;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值