本文最后更新于 3 年前 ,文中信息可能已经过时。如有问题请在评论区留言。

概要

本文代码基于 Java 17 实现

在不使用第三方工具类的情况下,将 List 去除重复数据并保持原数据的顺序。

解决思路有多种,本文只介绍以下四种处理方式。

方式一

使用 LinkedHashSet 删除 ArrayList 中的重复数据

LinkedHashSet 是在一个 ArrayList 删除重复数据的最佳方法。LinkedHashSet 在内部完成两件事:

  • 删除重复数据
  • 保持添加到其中的数据的顺序
java
1
2
3
public static <T> List<T> removeDuplicate(List<T> list) {
    return new ArrayList<>(new LinkedHashSet<>(list));
}

方式二

使用 Java 8 新特性 Stream 进行 List 去重

要从 ArrayList 中删除重复项,我们也可以使用 Java 8 Stream API。 使用 Stream 的 distinct() 方法返回一个由不同数据组成的流,通过对象的 equals() 方法进行比较。

java
1
2
3
public static <T> List<T> removeDuplicate(List<T> list) {
    return list.stream().distinct().toList();
}

方式三

利用 HashSet 不能重复添加数据的特性,由于 HashSet 不能保证添加顺序,所以只能作为判断条件保证顺序

java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public static <T> List<T> removeDuplicate(List<T> list) {
    HashSet<T> set = new HashSet<>(list.size());
    List<T> result = new ArrayList<>(list.size());
    for (T element : list) {
        if (set.add(element)) {
            result.add(element);
        }
    }
    return result;
}

方式四

利用 List 的 contains 方法循环遍历,重新排列,只添加一次数据,避免重复

java
1
2
3
4
5
6
7
8
9
public static <T> List<T> removeDuplicate(List<T> list) {
    List<T> result = new ArrayList<>(list.size());
    for (T element : list) {
        if (!result.contains(element)) {
            result.add(element);
        }
    }
    return result;
}

测试

以下测试基于 JUnit5 & AssertJ
java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.assertj.core.api.Assertions.*;

class ListRemoveDuplicateTest {

    private List<Integer> numbers;

    private List<Integer> expected;

    @BeforeEach
    void beforeEach() {
        numbers = new ArrayList<>(Arrays.asList(1, 1, 2, 3, 3, 3, 4, 5, 6, 6, 6, 7, 8, 9));
        expected = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8));
    }

    @Test
    void removeDuplicateTest() {
        List<Integer> listWithoutDuplicates = removeDuplicate(numbers);
        assertThat(listWithoutDuplicates).containsExactlyElementsOf(expected);
    }

    // 将这个方法修改为你要测试的方法
    public static List<T> removeDuplicate(List<T> list) {
        // todo Implement the method you want to test.
        return null;
    }
}