外贸网站dns北京seo顾问外包
HashMap 的 table
数组何时初始化?
答案:
table
数组在第一次调用 put()
方法时初始化。
为什么?
HashMap 为了节省内存,采用了“懒加载”机制。即使用 new HashMap()
创建对象时,只是计算了参数(如容量、负载因子),并没有真正创建底层数组。只有当第一次插入数据(put
)时,才会初始化 table
数组。
类比理解:
就像你买了一个书架(HashMap
),但卖家不会直接寄给你,而是等你第一次需要放书(put
)时,才根据你的需求(容量)组装好书架寄过来。
默认容量和扩容阈值是多少?
-
默认容量
默认容量是 16(数组长度)。
为什么是 16?
16 是经验值,在性能和内存占用之间取得平衡。容量必须是 2 的幂(原因与哈希计算优化有关)。 -
默认扩容阈值
默认阈值是 12(容量 × 负载因子)。
负载因子(默认 0.75)的作用:
阈值 = 容量 × 负载因子。当 HashMap 中的元素数量超过阈值时,触发扩容(数组翻倍)。
举个栗子 🌰
-
默认初始化:
HashMap<String, Integer> map = new HashMap<>();
- 此时
table
数组未初始化,容量和阈值均为 0。 - 当第一次调用
map.put("a", 1)
时:- 初始化
table
数组为长度 16。 - 计算阈值:16 × 0.75 = 12。
- 初始化
- 此时
-
触发扩容:
当插入第 13 个元素时,元素数量超过阈值 12,触发扩容:- 数组长度翻倍为 32。
- 新阈值变为 32 × 0.75 = 24。
用户指定容量时会发生什么?
如果通过构造函数指定容量(如 new HashMap(10)
):
- HashMap 会将其调整为最近的 2 的幂(例如 10 → 16)。
- 初始化时,阈值 = 调整后的容量 × 负载因子(例如 16 × 0.75 = 12)。
总结
场景 | 初始化时机 | 容量 | 扩容阈值 |
---|---|---|---|
默认构造函数 | 第一次 put() | 16 | 12(16×0.75) |
指定容量的构造函数 | 第一次 put() | 最近的 2 的幂 | 容量 × 负载因子 |
关键点:
- 容量始终是 2 的幂(优化哈希计算)。
- 扩容是为了减少哈希冲突,保证性能。