本文共 4727 字,大约阅读时间需要 15 分钟。
在日常的业务开发中,偶然会遇到需要将 List 集合中的重复数据去除的场景。这种情况下,开发者通常会考虑直接使用 Set 或 LinkedHashSet 来实现去重。然而,在实际业务开发中,情况往往比想象的复杂。例如,List 可能是历史遗留问题,或者是代码限制只能使用 List 接收数据,或者是代码写到一半时才发现问题。因此,在无法直接修改原有 List 类型或修改成本过高的情况下,以下 6 种去重方法将为你提供有效的解决方案。
在正式开始之前,我们需要明确两组概念:无序集合和有序集合,以及无序和有序的含义。这些概念在接下来的方法实现中将反复提及,因此在正式开始之前,先将它们搞清楚是非常必要的。
无序集合是指数据读取的顺序和数据插入的顺序不一致。例如,插入顺序是 1、5、3、7,而读取顺序却是 1、3、5、7。
有序集合的概念和无序集合的概念相反。它是指集合的读取顺序和插入顺序一致。例如,插入顺序是 1、5、3、7,读取顺序也是一致的。
通过上面的无序集合和有序集合的概念,我们可以得出有序和无序的概念。有序指的是数据的排列顺序和读取顺序符合我们的预期就叫做有序。而无序指的是数据的排列顺序和读取顺序不符合我们的预期就叫做无序。
要进行数据去重,我们可以新建一个集合,然后循环原来的集合,检查当前循环项是否存在于新集合中。如果不存在,则插入新集合中;如果存在,则舍弃。这种方法实现简单,且新集合的顺序与原集合一致。
public class ListDistinctExample { public static void main(String[] args) { Listlist = new ArrayList<>(); list.add(1); list.add(3); list.add(5); list.add(2); list.add(1); list.add(3); list.add(7); list.add(2); System.out.println("原集合:" + list); method(list); } public static void method(List list) { List newList = new ArrayList<>(list.size()); list.forEach(i -> { if (!newList.contains(i)) { newList.add(i); } }); System.out.println("去重集合:" + newList); }}
此方法不需要新建集合,而是通过迭代器逐个检查数据是否存在,如果存在多个相同的值,则删除最后一个重复项。这种方法实现代码较少,但新集合的顺序与原集合不一致。
public class ListDistinctExample { public static void main(String[] args) { Listlist = new ArrayList<>(); list.add(1); list.add(3); list.add(5); list.add(2); list.add(1); list.add(3); list.add(7); list.add(2); System.out.println("原集合:" + list); method_1(list); } public static void method_1(List list) { Iterator iterator = list.iterator(); while (iterator.hasNext()) { Integer item = iterator.next(); if (list.indexOf(item) != list.lastIndexOf(item)) { iterator.remove(); } } System.out.println("去重集合:" + list); }}
HashSet 天生具备去重特性,因此可以通过将 List 转换为 HashSet 来实现去重。这种方法实现代码简洁,但新集合的顺序会被 HashSet 自动排序。
public class ListDistinctExample { public static void main(String[] args) { Listlist = new ArrayList<>(); list.add(1); list.add(3); list.add(5); list.add(2); list.add(1); list.add(3); list.add(7); list.add(2); System.out.println("原集合:" + list); method_2(list); } public static void method_2(List list) { HashSet set = new HashSet<>(list); System.out.println("去重集合:" + set); }}
为了保留原集合的顺序,LinkedHashSet 是一个更好的选择。它既能去重,又能保持集合的顺序。
public class ListDistinctExample { public static void main(String[] args) { Listlist = new ArrayList<>(); list.add(1); list.add(3); list.add(5); list.add(2); list.add(1); list.add(3); list.add(7); list.add(2); System.out.println("原集合:" + list); method_3(list); } public static void method_3(List list) { LinkedHashSet set = new LinkedHashSet<>(list); System.out.println("去重集合:" + set); }}
TreeSet 也可以用来实现去重,但其默认排序特性会导致顺序与原集合不一致,因此通常不推荐用于需要保持顺序的场景。
public class ListDistinctExample { public static void main(String[] args) { Listlist = new ArrayList<>(); list.add(1); list.add(3); list.add(5); list.add(2); list.add(1); list.add(3); list.add(7); list.add(2); System.out.println("原集合:" + list); method_4(list); } public static void method_4(List list) { TreeSet set = new TreeSet<>(list); System.out.println("去重集合:" + set); }}
JDK 8 引入的 Stream API 提供了一种简洁的去重方法。通过 Stream 的 distinct() 方法,可以轻松实现去重,且新集合的顺序与原集合一致。
public class ListDistinctExample { public static void main(String[] args) { Listlist = new ArrayList<>(); list.add(1); list.add(3); list.add(5); list.add(2); list.add(1); list.add(3); list.add(7); list.add(2); System.out.println("原集合:" + list); method_5(list); } public static void method_5(List list) { list = list.stream().distinct().collect(Collectors.toList()); System.out.println("去重集合:" + list); }}
本文介绍了 6 种去重方法,其中实现最简洁且能保持顺序的方法是使用 LinkedHashSet 和 Stream 去重。前者无需额外依赖,后者代码简洁且功能强大。选择哪种方法取决于具体需求和场景。
转载地址:http://dzufk.baihongyu.com/