java中hashset去重利用其不允许重复元素的特性,直接初始化可自动过滤重复项但不保证顺序;需保序用linkedhashset;自定义对象须重写equals和hashcode;stream.distinct()底层基于linkedhashset,兼顾去重与顺序。

Java 中用 HashSet 去重列表,核心是利用其**不允许重复元素**的特性:将列表元素全部添加进 HashSet,重复项会自动被忽略,再转回列表即可。
直接构造 HashSet 去重(推荐)
最简洁的方式是用列表直接初始化 HashSet,它会在构建过程中自动过滤重复元素:
List<string> original = Arrays.asList("a", "b", "a", "c", "b");
Set<string> uniqueSet = new HashSet(original);
List<string> uniqueList = new ArrayList(uniqueSet); // 若需 List 类型
</string></string></string>
⚠️ 注意:顺序不保证。HashSet 不维护插入顺序,结果列表元素顺序可能与原列表不同。
保持插入顺序?用 LinkedHashSet
如果需要**去重同时保留首次出现的顺序**,应使用 LinkedHashSet:
- 它继承自
HashSet,同样去重 - 内部用链表维护插入顺序,遍历时按添加顺序返回
List<string> original = Arrays.asList("a", "b", "a", "c", "b");
Set<string> uniqueSet = new LinkedHashSet(original);
List<string> uniqueList = new ArrayList(uniqueSet); // ["a", "b", "c"]
</string></string></string>
对自定义对象去重:必须重写 equals() 和 hashCode()
若列表中是自定义类(如 User),仅靠 HashSet 默认行为无法正确去重,因为默认比较的是对象引用。
必须在该类中:
- 重写
equals()方法(定义“两个对象相等”的逻辑,比如 id 相同即相等) - 重写
hashCode()方法(确保相等的对象有相同哈希值,否则HashSet查找失效)
✅ 正确示例(Lombok 可简化):
@Data // Lombok 自动生成 getter/setter/equals/hashCode/toString
public class User {
private Long id;
private String name;
}
// 使用方式不变:
List<user> users = Arrays.asList(new User(1L, "Alice"), new User(1L, "Alice"));
Set<user> uniqueUsers = new HashSet(users); // 自动去重(id 相同视为重复)
</user></user>
一行流式写法(Java 8+)
配合 Stream API,可写成链式调用:
List<string> uniqueList = original.stream()
.distinct() // 内部使用 LinkedHashSet 保证顺序和去重
.collect(Collectors.toList());
</string>
✅ Stream.distinct() 底层正是基于 LinkedHashSet 实现,既去重又保序,适合函数式风格。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











