HashMap的扩容机制------resize()

一:首先要知道HashMap什么时候扩容
当元素向HashMap容器中添加元素的时候,会判断当前元素的个数,如果当前元素的个数大于等于阈值时,即当前数组table的长度*加载因子就要进行自动扩容。

由于HashMap的底层数据结构是“链表散列”,即数组和链表的组合,而数组是无法自动扩容的,所以只能是换一个更大的数组去装填以前的元素和将要添加的新元素

分析resize()方法的源代码可以发现:在jdk1.7以前,resize()方法传入的参数是新数组的容量,HashMap也不是无限能扩容的,1:方法中会首先判断扩容前的旧数组容量是否已经达到最大即2^30了,如果达到了就修改阈值为int的最大取值,这样以后就不会扩容了。
2:初始化一个新Entry数组;
3:计算rehash,判断扩容的时候是否需要重新计算hash值,将此值作为参数传入到transfer方法中;这个是和jdk1.8不同的一点,待会看1.8
4:通过transfer方法将旧数组中的元素复制到新数组,在这个方法中进行了包括释放就的Entry中的对象引用,该过程中如果需要重新计算hash值就重新计算,然后根据indexfor()方法计算索引值。而索引值的计算方法为{ return h & (length-1) ;}即hashcode计算出的hash值和数组长度进行与运算。。。。。jdk1.7中重新插入到新数组的元素,如果原来一条链上的元素又被分配到同一条链上那么他们的顺序会发生倒置这个和1.8也不一样

二:jdk1.

### Java HashMap 扩容机制解释 #### 构造函数中的重要参数 在探讨 `HashMap` 的扩容机制之前,理解其构造函数中的两个关键参数至关重要。这两个参数分别是初始容量(initial capacity)和加载因子(load factor)。这些参数决定了何时以及如何执行扩容操作[^1]。 #### 触发条件 当 `HashMap` 中存储的元素数目超过了当前容量乘以加载因子的结果时,即达到了阈值(threshold),此时便会触发扩容动作。具体来说,默认情况下,一旦条目数达到或超过此界限,系统便认为有必要增加内部数组尺寸来维持高效能运作[^2]。 #### 扩容过程概述 由于 Java 数组不具备自动调整大小的功能,在实际发生扩容时,程序会创建一个新的桶数组,其长度通常是原数组长度的两倍。随后,所有现存映射关系会被重新散列并放置于新的更大空间里。对于那些没有经历哈希碰撞的情况下的节点而言,它们的新索引可以通过简单的位运算 `(e.hash & (newCap - 1))` 来确定;而对于已经形成链表或者红黑树结构的部分,则需进一步处理: - 如果是普通的单向链接列表形式,则要逐一遍历整个链条,并依据特定规则决定各结点应迁移到何处; - 若涉及到了更复杂的红黑树情形下新增加的数据项同样遵循上述原则定位最终归属位置[^4]。 #### 性能考量 尽管这种按需扩展策略有助于保持良好的时间复杂度表现——平均查找时间为 O(1),但在每次真正实施扩容期间不可避免地会产生额外开销。这是因为不仅涉及到内存分配请求,还需要完成旧有记录迁移工作,这可能会暂时降低整体吞吐量直至全部转移完毕为止。因此合理设置初始化容量可以有效减少不必要的重建次数从而优化应用性能[^3]。 ```java // 示例代码展示简单版put方法逻辑简化示意 public V put(K key, V value) { // ...省略其他部分... if (++size > threshold) resize(); // ...继续后续流程... } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值