HashMap的扩容过程

一:扩容条件

在Java中,HashMap的扩容条件是基于当前HashMap容量(即内部数组的大小)和实际存储元素的数量。具体来说,在Java 7及以后版本中,HashMap扩容的触发条件如下:
1,装载因子阈值: 当HashMap中的元素数量(entry数量)超过当前容量与预设的负载因子(load factor)的乘积时,会触发扩容操作。默认负载因子为0.75,也就是说,当HashMap中的元素个数达到容量的75%时,就会进行扩容。

2,插入新元素时: 在执行put()操作尝试插入一个新的键值对时,如果发现现有元素数量已经达到了扩容阈值,并且确实需要新增一个元素(不是替换已存在的元素),那么也会触发扩容操作。
扩容过程涉及创建一个新的、更大容量的数组,并将原数组中的所有键值对重新计算哈希值并移动到新的数组中。这个过程也称为“rehashing”,并且在Java 8中引入了优化,链表长度大于某个阈值时会转化为红黑树,以减少搜索、插入和删除的时间复杂度。

二:举例说明:

初始容量为16,当添加第13个元素时,HashMap扩容的流程是什么样的

当初始容量为16的HashMap添加第13个元素时,由于默认负载因子是0.75,所以扩容阈值(threshold)计算公式为:capacity * loadFactor = 16 * 0.75 = 12。

因此,当添加第13个元素时,HashMap的实际存储元素数量超过了扩容阈值(即当前已存储12个元素+即将添加的第13个元素),将会触发扩容操作。

扩容流程如下

创建新的Entry数组: HashMap会创建一个新的Entry数组,其容量通常是原来容量的两倍加一,也就是newCapacity = oldCapacity << 1 = 16 * 2 = 32。

重新哈希所有元素: 遍历原HashMap中的每个Entry(键值对),使用新的容量重新计算它们的索引位置,并将这些Entry放入新的数组中。这个过程被称为“rehash”。

链表拆分或树形结构调整: 如果在扩容过程中某个桶(bucket)下形成了链表结构,那么在这个桶下的链表会根据新的索引被拆分成两个链表,分别存放在新数组的相应位置。在Java 8及以上版本中,如果链表长度超过8且HashMap允许转化为红黑树(通过treeifyThreshold控制,默认也是8),则链表会被转换为红黑树。

替换引用: 扩容完成后,HashMap会将内部引用指向新的Entry数组,旧数组将不再使用,随后垃圾回收机制会在适当的时候回收旧数组。

这样就完成了HashMap的扩容操作,之后可以继续安全地添加新的元素,而不会因为超出容量限制导致无法插入。

小提醒:
HashMap初始化之后,并没有立即分配内存空间,初始化时并没有初始化数组 table,在 put 操作时才初始化;

相关推荐

  1. HashMap扩容过程

    2024-01-26 12:16:03       49 阅读
  2. 24.HashMap扩容机制

    2024-01-26 12:16:03       42 阅读
  3. HashMap扩容机制

    2024-01-26 12:16:03       41 阅读
  4. HashMap 扩容因子为什么是 0.75?

    2024-01-26 12:16:03       40 阅读
  5. HashMap在Jdk1.8之前并发扩容死循环

    2024-01-26 12:16:03       38 阅读
  6. Rust HashMap

    2024-01-26 12:16:03       42 阅读
  7. Rust 语言 HashMap

    2024-01-26 12:16:03       42 阅读
  8. HashMap简单原理

    2024-01-26 12:16:03       41 阅读
  9. HashMap底层结构

    2024-01-26 12:16:03       44 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-26 12:16:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-26 12:16:03       100 阅读
  3. 在Django里面运行非项目文件

    2024-01-26 12:16:03       82 阅读
  4. Python语言-面向对象

    2024-01-26 12:16:03       91 阅读

热门阅读

  1. 第28章复数矩阵到微分,乘法以及除法

    2024-01-26 12:16:03       54 阅读
  2. 极简pandas库Series

    2024-01-26 12:16:03       56 阅读
  3. 2401llvm,clang转换器

    2024-01-26 12:16:03       48 阅读
  4. 2401llvm,clang插件

    2024-01-26 12:16:03       55 阅读
  5. conda常用命令总结

    2024-01-26 12:16:03       60 阅读
  6. ·策略模式

    2024-01-26 12:16:03       52 阅读
  7. conda使用,pip使用

    2024-01-26 12:16:03       58 阅读
  8. 解决linux下wps缺失字体的问题

    2024-01-26 12:16:03       60 阅读
  9. 低代码开发助力业务效能高速提升

    2024-01-26 12:16:03       61 阅读
  10. C++(2) 结构体和动态数组的实现

    2024-01-26 12:16:03       45 阅读