HashSet元素不重复原理详解
时间:2026-03-27 09:30:50 267浏览 收藏
HashSet的去重奥秘其实藏在HashMap的键唯一性机制中——它将所有元素作为内部HashMap的key存储,用一个静态空对象PRESENT作统一value,从而天然规避重复;真正决定“是否重复”的关键在于hashCode()与equals()方法的协同作用:先通过哈希值快速定位桶位置,再用equals()精确比对内容,因此自定义类必须同时重写这两个方法才能正确去重;其add操作本质就是map.put(e, PRESENT)的封装,靠返回值是否为null来判定添加成功与否,而无序、允许单个null、线程不安全等特性,不过是底层HashMap行为的自然延伸。

HashSet靠HashMap的键唯一性实现去重
HashSet本身不直接管理元素是否重复,而是把所有元素作为内部HashMap的key来存储,value统一用一个空对象(PRESENT)占位。因为HashMap规定同一个key只能存在一份,所以只要元素能被正确识别为“同一个key”,就不会重复添加。
判断重复依赖hashCode和equals两个方法
往HashSet里add一个对象时,会按以下顺序判断:
- 先调用该对象的
hashCode(),算出哈希值,定位到哈希表中某个桶(数组位置) - 如果桶为空,直接存入
- 如果桶已有元素,就逐个调用
equals()比较——只有当hashCode()相同 且equals()返回true,才认定是重复元素,跳过添加
注意:自定义类(比如Student)若想在HashSet中正确去重,必须同时重写hashCode()和equals(),否则默认按内存地址比较,两个内容相同的对象也会被当成不同元素。
底层操作其实就是HashMap.put()
看源码就能确认这一点:
HashSet.add(e)内部调用的是map.put(e, PRESENT)- 而
HashMap.put()在发现key已存在时,会用新value覆盖旧value,并返回旧value;如果key不存在,则返回null - 所以HashSet的add方法靠
put(...) == null来判断是否真正新增成功
无序、允许null、线程不安全是附带特性
这些不是去重机制本身决定的,而是由底层HashMap行为自然带来的:
- 无序:哈希值决定存放位置,和插入顺序无关
- 允许一个null:HashMap允许key为null,且只允许一个(null的hashCode固定为0)
- 线程不安全:HashMap非同步,多个线程同时add可能引发数据错乱或丢失
好了,本文到此结束,带大家了解了《HashSet元素不重复原理详解》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多文章知识!
相关阅读
更多>
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
最新阅读
更多>
-
443 收藏
-
493 收藏
-
200 收藏
-
288 收藏
-
387 收藏
-
347 收藏
-
279 收藏
-
480 收藏
-
276 收藏
-
189 收藏
-
215 收藏
-
278 收藏
课程推荐
更多>
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习