java中map的clear()方法仅清空键值对并重置size和threshold,不改变底层table数组容量,后续put复用原数组空间,不会立即扩容。

Java 中 Map 接口的 clear() 方法并不会重置底层哈希表的容量,后续 put() 操作仍会复用原有数组空间,不会立即触发扩容 —— 但是否真正“复用”,取决于具体实现类(如 HashMap)和 JDK 版本。
HashMap 的 clear() 不改变 table 数组引用和长度
HashMap 的 clear() 只是将所有桶(bucket)设为 null,并重置 size 和 modCount,但底层的 Node[] table 数组本身未被替换或缩容。也就是说:
- 原数组对象仍被持有,内存未释放(除非 GC 时无其他引用)
- 数组长度(capacity)保持不变,比如原来是 16,clear 后仍是 16
- 下次
put时直接在原数组上插入,无需重建数组
扩容阈值(threshold)也被重置,但 capacity 不变
clear() 会把 size = 0,同时将 threshold 重置为初始阈值(例如默认构造下为 12),但 capacity(即 table.length)不变。这意味着:
- 刚 clear 后第一次 put,只要 size ≤ threshold,就不会扩容
- 若之前 map 已扩容到 64,clear 后再 put 13 个元素,仍会在第 13 次 put 触发扩容(因为 threshold 是 64 × 0.75 = 48?不对!注意:threshold 在 clear 时会被重设为「初始容量 × loadFactor」或继承自上次 resize 的值,实际逻辑更细)
- JDK 8+ 中,
clear()会调用resize()吗?不会。它只清空节点,不调用 resize
不同构造方式影响 clear 后的初始行为
clear 后的首次 put 是否触发扩容,还取决于 map 创建时的初始化方式:
- 无参构造:
new HashMap()→ 初始 table 为null,首次 put 才初始化为 length=16;clear 后再次 put,因 table 非 null,直接使用原数组 - 指定初始容量:
new HashMap(32)→ table 直接分配 length=32;clear 后 put,复用该数组,直到 size 超过32 × 0.75 = 24才扩容 - 从集合构造:
new HashMap(map)→ 容量按 map.size() / loadFactor 向上取 2 的幂;clear 后同样复用该容量
LinkedHashMap 和 ConcurrentHashMap 行为略有差异
虽然都实现 Map 接口,但底层策略不同:
-
LinkedHashMap:clear 行为与 HashMap 一致,复用 table,维护双向链表头尾指针归零 -
ConcurrentHashMap:clear 是分段/分桶清理,不改变 baseSize 或 sizeCtl;各 bin 独立清空,put 时按需初始化对应桶,整体容量结构不变 -
WeakHashMap:clear 会清除所有 key 的弱引用,table 可能被 GC 回收,但若未回收,后续 put 仍尝试复用
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











