天天看点

去除 List 中的重复元素,你知道几种实现方法?

作者:coderTT

去除List中重复元素,这在实际编程或面试中经常遇到,每个人都有习惯的写法吧,这里抛砖引玉,汇总了一些实现方案,开拓思路。

准备数据

假设数组中有10个数据,可能有重复,需要将重复的数据从数组中去掉。

public List<String> initList = Arrays.asList(
    "张三", 
    "李四", 
    "张三", 
    "周一", 
    "刘四", 
    "李强", 
    "李白", 
    "张三", 
    "李强", 
    "王五"
);           

方案一,for循环

public void remove1() {
    List<String> list = new ArrayList(initList);
    List<String> list2 = new ArrayList<>();
    for (String element : list) {
        if (!list2.contains(element)) {
            list2.add(element);
        }
    }
    System.out.println(list2);
}
// [张三, 李四, 周一, 刘四, 李强, 李白, 王五]           

最常用的实现思路,创建一个空的 List,判断是否存,不存在才添加,这样就保证了元素不重复。

方案二,嵌套循环

public void remove2() {
    List<String> list = new ArrayList(initList);
    for (int i = 0; i < list.size() - 1; i++) {
        for (int j = list.size() - 1; j > i; j--) {
            if (list.get(j).equals(list.get(i))) {
                list.remove(j);
            }
        }
    }
    System.out.println(list);
}           

利用双循环,判断是否有相等的,再进行移除。

方案三,比对index

public void remove3() {
    List<String> list = new ArrayList(initList);
    List<String> list2 = new ArrayList(initList);
    for (String element : list2) {
        if (list.indexOf(element) != list.lastIndexOf(element)) {
            list.remove(list.lastIndexOf(element));
        }
    }
    System.out.println(list);
}           

复制两个数组,判断 list 中的元素的首尾出现的坐标位置是否一致,如果一致说明没有重复的,否则重复,再删除重复位置的元素。

方案四,借助Set的特性进行去重

public void remove4() {
    List<String> list = new ArrayList(initList);
    List<String> list2 = new ArrayList(new HashSet(list));
    System.out.println(list2);
}           

Set 数据结构是利用hash判断重复数据,只保留一份。把 List 先装进 HashSet,然后再装回来,这样就保证了元素的不重复。

方案五,Stream去重

public void remove5() {
    List<String> list = new ArrayList(initList);
    list = list.stream().distinct().collect(Collectors.toList());
    System.out.println(list);
}           

利用 Stream 的 distinct 方法去重,这个方法也十分简单,一行代码搞定!

性能比较

随机生成100000个字符串,分别测试五种方案的运行时间:

方案一:27ms

方案二:355ms

方案三:400ms

方案四:14ms

方案五:52ms

结论:利用Set去重,效率最高,但不保证顺序,保证顺序可以使用LinkedHashSet。从可读性考虑,如果不是数据量特别大的场景,更推荐stream。

继续阅读