HashSet通过HashMap实现去重,元素作key、PRESENT作value,依赖hashCode()和equals()判断重复;自定义类需重写这两方法,否则无法正确去重。

HashSet 通过内部的 HashMap 实现元素唯一性,添加时自动忽略重复值,无需手动判断。
HashSet 的去重原理
HashSet 底层基于 HashMap,每个元素作为 key 存入 map,value 固定为一个空对象(PRESENT)。由于 HashMap 的 key 不允许重复,且 HashSet 在 put 时调用 hashCode() 和 equals() 判断是否已存在相同元素,因此能天然保证唯一性。
- 添加元素时,先计算 hash 值定位桶位置
- 若桶中已有元素,则调用 equals() 比较内容是否相等
- 两者都相等 → 认为重复,不插入;否则插入新节点
正确使用 HashSet 去重的关键点
自定义类存入 HashSet 时,必须重写 hashCode() 和 equals() 方法,否则即使内容相同也会被当作不同对象。
- 两个对象 equals() 返回 true → hashCode() 必须返回相同值
- IDE(如 IntelliJ)可一键生成这两个方法(Alt+Insert → “Generate…” → “equals() and hashCode()”)
- 使用 Lombok 的 @EqualsAndHashCode 注解可自动处理(需配合 @Data 或显式指定字段)
常见去重场景示例
从 List 中提取不重复元素、过滤重复字符串或对象:
立即学习“Java免费学习笔记(深入)”;
- 字符串去重:new HashSet(Arrays.asList("a", "b", "a")) → 自动保留 "a", "b"
- List 转无重复 Set:Set
unique = new HashSet(originalList) - 对象去重:确保实体类已重写 hashCode/equals,再 add 进 HashSet
注意:HashSet 不保证顺序
如果需要按插入顺序保留唯一元素,改用 LinkedHashSet;若需排序后去重,用 TreeSet(但要求元素可比较)。
- LinkedHashSet:保持插入顺序,性能略低于 HashSet
- TreeSet:按自然序或 Comparator 排序,add 时间复杂度为 O(log n)


















