HashSet底层原理

该文章已生成可运行项目,

以下是 HashSet 的底层原理的详细解析,结合数据结构、哈希冲突处理、扩容机制及线程安全性等核心要点:


一、底层实现:基于 HashMap 的包装类

HashSet 的底层通过 HashMap 实现,所有元素均存储为 HashMap 的键(Key),而值(Value)统一使用一个静态常量 PRESENTprivate static final Object PRESENT = new Object())占位。这种设计使得 HashSet 的元素唯一性完全依赖 HashMap 的键不可重复特性。

数据结构示意图

HashSet 实例
└── 内部 HashMap
    ├── 数组 (Buckets)
    │   ├── 索引0 → 链表/红黑树节点(元素1 → 元素2 → ...)
    │   ├── 索引1 → null
    │   ├── 索引2 → 红黑树根节点(元素3 → ...)
    │   └── ... 
    └── 负载因子(默认 0.75)、容量(默认 16)

二、核心操作流程

1. 添加元素(add(e)

哈希值计算:调用元素的 hashCode() 方法生成哈希码,再通过哈希函数 (h = key.hashCode()) ^ (h >>> 16) 计算最终哈希值。
确定桶位置:哈希值对数组长度取模((n-1) & hash),确定元素应存放的桶索引。
冲突处理
桶为空:直接插入新节点。
桶为链表:遍历链表,通过 equals() 判断是否重复。若无重复,插入链表尾部;若链表长度≥8且数组长度≥64,链表转为红黑树。
桶为红黑树:调用红黑树插入逻辑,确保元素唯一性。

2. 删除元素(remove(o)

• 通过哈希值定位桶,遍历链表或红黑树找到目标节点,调整指针移除节点。若红黑树节点数≤6,退化为链表。

3. 查询元素(contains(o)

• 哈希值定位桶后,遍历链表或红黑树,通过 equals() 判断是否存在目标元素。


三、构造方法与扩容机制

1. 构造方法

默认构造器:初始化容量为 16,负载因子 0.75。
指定容量/负载因子:直接传递参数至内部 HashMap。
基于集合构造:初始容量为 Math.max(集合大小 / 0.75 + 1, 16),避免频繁扩容。

</
本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值