在 Java 开发中,数据去重是常见的需求,无论是处理集合、数组还是数据库查询结果,都需要高效的去重方法,本文将介绍几种主流的 Java 去重方案,涵盖基础语法到高级应用,帮助开发者根据场景选择合适的方法。

利用 Set 集合自动去重
Set 接口是 Java 中专门用于存储不重复元素的集合,其实现类 HashSet、LinkedHashSet 和 TreeSet 各具特点,是最常用的去重工具。
使用 HashSet
HashSet 基于 HashMap 实现,添加元素时通过 hashCode() 和 equals() 方法判断唯一性,去重效率高(平均时间复杂度 O(1)),但元素顺序无保证。
List<String> list = Arrays.asList("a", "b", "a", "c", "b");
Set<String> set = new HashSet<>(list); // 利用构造方法直接去重
List<String> distinctList = new ArrayList<>(set); // 转换回 List
使用 LinkedHashSet
若需保留元素的插入顺序,可选择 LinkedHashSet,它在 HashSet 基础上维护了一个双向链表,去重的同时记录元素顺序,适用于需要稳定输出结果的场景。
Set<String> linkedSet = new LinkedHashSet<>(list); List<String> orderedList = new ArrayList<>(linkedSet);
使用 TreeSet
TreeSet 基于 TreeMap 实现,元素会按照自然顺序或自定义 Comparator 排序,若需去重并排序,可选用 TreeSet,但插入效率略低于 HashSet(时间复杂度 O(log n))。

Set<String> treeSet = new TreeSet<>(list); // 默认字典序排序 List<String> sortedList = new ArrayList<>(treeSet);
Stream API 去重(Java 8+)
Java 8 引入的 Stream 为集合操作提供了函数式编程风格,其 distinct() 方法可轻松实现去重,同时支持自定义去重逻辑。
基础去重
直接调用 distinct() 方法,返回一个去重后的流,适用于简单场景。
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4, 5);
List<Integer> distinctNumbers = numbers.stream()
.distinct()
.collect(Collectors.toList());
自定义去重条件
若需根据对象的某个属性去重,可通过 filter() 结合 Collectors.toMap() 或 Collectors.groupingBy 实现,对 User 对象按 id 去重:
List<User> users = Arrays.asList(new User(1, "Alice"), new User(2, "Bob"), new User(1, "Alice"));
List<User> distinctUsers = users.stream()
.collect(Collectors.toMap(
User::getId, // 去重依据的属性
user -> user,
(existing, replacement) -> existing // 重复时保留第一个
))
.values()
.stream()
.collect(Collectors.toList());
自定义对象去重的注意事项
当处理自定义对象时,HashSet 和 TreeSet 需要正确重写 hashCode() 和 equals() 方法(TreeSet 还需实现 Comparable 接口或提供 Comparator),否则去重会失效。

class User {
private int id;
private String name;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return id == user.id;
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
数组去重方法
对于数组,可先转换为 List,再使用上述 Set 或 Stream 方法去重,最后转回数组:
String[] array = {"a", "b", "a", "c"};
String[] distinctArray = Arrays.stream(array)
.distinct()
.toArray(String[]::new);
性能对比与选择建议
- HashSet:适合无需顺序的高效去重,性能最佳。
- LinkedHashSet:需保留插入顺序时的首选。
- TreeSet:需排序时使用,但注意性能损耗。
- Stream API:代码简洁,支持复杂去重逻辑,适合函数式编程风格。
根据实际场景需求,结合性能、顺序和代码可读性选择合适的方法,可高效解决 Java 开发中的去重问题。

















