List 是我们在开发中常用的数据结构,是有序且可重复的集合,既然是可重复的集合,开发中我们也常常需要对其做去重操作,在 Java 中,我们可以使用多种方式完成 List 的去重。

遍历 List 删重

public static List<?> removeDuplicate(List<?> list) {
    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);
            }
        }
    }
    return list;
} 

该方法通过循环 List 中的所有元素然后删除重复项达到去重。

遍历把未重复的元素存入另一个 List

public static List<?> removeDuplicate(List<?> list) {
    List tempList = new ArrayList();
    for (int i = 0; i < list.size(); i++) {
        if (!tempList.contains(list.get(i))) {
            tempList.add(list.get(i));
        }
    }
    return tempList;
}

增加了另一个 List 来作存储,把原 List 的元素和新 List 的元素比较,如新 List 中没有该元素,则将该元素存入新 List

通过 HashSet 剔除重复元素

public static List<?> removeDuplicate(List<?> list) {
    Set h = new HashSet(list);
    list.clear();
    list.addAll(h);
    return list;
}

Set 是无序、不可重复的集合,正是其不允许重复元素的特点,通过 ListSet 互转,可以去掉重复元素。

保持顺序删除 ArrayList 中重复元素

public static List<?> removeDuplicateWithOrder(List<?> list) {
    Set<Object> set = new HashSet<>();
    List tempList = new ArrayList<>();
    for (Object element : list) {
        if (set.add(element))
            tempList.add(element);
    }
    return tempList;
}

虽然同样用到了 HashSet,但加入了逻辑使其保持顺序。

LinkedHashSet 高效去重

public static List<?> removeDuplicate(List<?> list) {
    Set set = new LinkedHashSet(list);
    list.clear();
    list.addAll(set);
    return list;
}

利用 LinkedHashSet 不能添加重复数据并能保证添加顺序的特性,该方法效率非常高。

Java 8 的 Stream 去重

public static List<?> removeDuplicate(List<?> list) {
    return list.stream().distinct().collect(Collectors.toList());
}

Java 8 支持 Stream 流操作,因此集合去重可以简单地实现。


上面的部分代码我为了方便演示就直接在传入的 List 上做去重了,在实际使用中,应根据项目实际情况来判断,假如原 List 在去重后仍会继续使用,就应该创建一个新的 List 来存储去重后的元素,避免项目出现意想不到的 Bug。

另外,为了可复用性,我没有指定 List 的类型,而是使用泛型无界通配符 ?,在 IDE 中可能会报警告,按需修复即可。