在Java里如何去除List中的重复项_Java列表去重常用技巧

Java去重List推荐用Li

nkedHashSet或Stream.distinct(),均保序且高效;自定义对象按字段去重需用Collectors.toMap();HashSet不保序,TreeSet可排序去重,手动遍历效率低不推荐。

Java中去除List重复元素,核心思路是借助具备唯一性约束的集合(如HashSet、LinkedHashSet、TreeSet)或Stream API来实现。选择哪种方式,取决于你是否需要保持原有顺序、是否要求元素可比较、以及对性能的要求。

用LinkedHashSet保持插入顺序去重

这是最常用也最推荐的方式,适合大多数场景——既去重,又保留原List中元素首次出现的顺序。

  • 创建一个LinkedHashSet,把原List全部添加进去,自动去重且记序
  • 再用这个Set构造新ArrayList(或清空原List后重新添加)
示例代码:
List list = Arrays.asList("a", "b", "a", "c", "b");
List uniqueList = new ArrayList<>(new LinkedHashSet<>(list));

注意:元素必须正确重写equals()hashCode(),否则自定义对象去重会失效。

用Stream.distinct()一行解决(Java 8+)

函数式风格简洁清晰,同样默认保持原始顺序,底层也是基于LinkedHashSet实现的去重逻辑。

  • 调用stream().distinct().collect(Collectors.toList())
  • 适用于临时去重、链式调用场景,可与其他Stream操作组合
示例代码:
List nums = Arrays.asList(1, 2, 2, 3, 1);
List unique = nums.stream().distinct().collect(Collectors.toList());

按业务规则去重(如根据对象某个字段)

当List中是自定义对象(如User),而你只想根据id或name去重时,不能直接用HashSet——需配合Collectors.toMap()或自定义谓词。

  • toMap()以关键字段为key,保留第一个出现的对象
  • 再取map.values()转为List,自然去重且保序(Java 9+可用LinkedHashMap::new确保顺序)
示例(按id去重User):
List users = ...;
List uniqueById = users.stream()
    .collect(Collectors.toMap(User::getId, u -> u, (u1, u2) -> u1, LinkedHashMap::new))
    .values()
    .stream()
    .collect(Collectors.toList());

其他方式简要说明

HashSet适合不关心顺序的快速去重;TreeSet可用于需要排序后去重的场景(要求元素实现Comparable或传入Comparator);手动遍历+contains判断效率低,仅用于极小数据量或教学演示,不建议生产使用。

基本上就这些。选LinkedHashSet或Stream.distinct()覆盖90%需求,按字段去重稍复杂但很实用——关键还是看你的数据结构和业务约束。