HashSet的底层实现原理?
请解释Java中HashSet的底层实现原理,包括如何基于HashMap实现元素存储、如何保证元素唯一性、以及加载因子和初始容量对性能的影响。
回答
古法程序员
HashSet:底层基于HashMap实现。
- 实际存储:将元素作为HashMap的key,value统一为PRESENT常量(new Object())
- 构造方法:new HashMap<>() 创建底层Map
唯一性保证:
- 通过HashMap的put()机制保证:先计算key的hashCode定位桶,再遍历链表用equals判断是否已存在
- 存在相同key → put()返回旧值(非null),HashSet的add()返回false
- 不存在 → put()返回null,add()返回true
注意:存入HashSet的元素必须正确重写hashCode()和equals(),否则无法保证唯一性。
初始容量和加载因子:
- 默认初始容量16,加载因子0.75
- 当size > capacity * loadFactor时扩容为2倍
- 大容量预计元素较多时,应指定初始容量以减少扩容开销
- 加载因子过高(如0.9)节省内存但增加哈希冲突
- 加载因子过低(如0.5)减少冲突但浪费内存
性能:
- add/remove/contains:平均O(1),最差O(n)(大量哈希冲突时)
- 迭代顺序不保证,与HashMap的迭代顺序一致(即桶序+链表序)