size()直接返回hashmap内部维护的size字段值,该字段在add/remove时同步增减,故为o(1)操作;clear()则委托hashmap清空桶数组、重置size为0并更新modcount。

HashSet 的 size() 方法直接返回内部元素个数,清空用 clear() 方法——两者都是 O(1) 时间操作,不涉及哈希计算或遍历。
size() 是怎么得到的?
HashSet 内部由 HashMap 实现(JDK 8+),它把所有元素作为 key 存进 HashMap,value 固定为一个静态的 PRESENT 对象。HashMap 自己维护了一个 size 字段,每次 add 或 remove 成功时就增减 1。所以调用 set.size() 只是直接读这个字段,不需要遍历或重新统计。
clear() 做了什么?
调用 set.clear() 会委托给底层 HashMap 的 clear() 方法,主要做两件事:
- 把所有桶(bucket)数组里的链表或红黑树节点全部断开引用
- 重置 size 字段为 0,同时把 modCount(修改计数器)加 1,以支持 fail-fast 迭代器检测
注意:它不会立即回收内存,只是让原有对象变为可被 GC 回收的状态;数组本身通常也不会缩容,只是清空内容。
实际使用注意点
这两个方法都线程不安全。如果在多线程环境下并发调用 size() 和 clear(),或者一边遍历一边 clear(),可能看到不一致的 size 值,甚至触发 ConcurrentModificationException。
- 需要线程安全?考虑用
Collections.synchronizedSet(new HashSet())或ConcurrentHashMap.newKeySet()(JDK 8+) - 想确认是否真清空了?可以再调用一次 size() 看是否为 0,但不要依赖它做逻辑判断(除非已确保无并发)
- clear() 后集合仍可继续 add,无需重新 new
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











