Перейти к основному содержимому

Удаление всех дубликатов из списка в Java

· 3 мин. чтения

1. Введение

В этом кратком руководстве мы узнаем , как удалить повторяющиеся элементы из списка. Сначала мы будем использовать обычную Java, затем Guava и, наконец, решение на основе Java 8 Lambda.

Этот учебник является частью серии « Java — Back to Basic » здесь, на ForEach.

2. Удалите дубликаты из списка, используя обычную Java

Мы можем легко удалить повторяющиеся элементы из списка с помощью стандартной Java Collections Framework через Set :

public void 
givenListContainsDuplicates_whenRemovingDuplicatesWithPlainJava_thenCorrect() {
List<Integer> listWithDuplicates = Lists.newArrayList(5, 0, 3, 1, 2, 3, 0, 0);
List<Integer> listWithoutDuplicates = new ArrayList<>(
new HashSet<>(listWithDuplicates));

assertThat(listWithoutDuplicates, hasSize(5));
assertThat(listWithoutDuplicates, containsInAnyOrder(5, 0, 3, 1, 2));
}

Как мы видим, исходный список остался без изменений.

В приведенном выше примере мы использовали реализацию HashSet , которая представляет собой неупорядоченную коллекцию. В результате порядок очищенного listWithoutDuplicates может отличаться от порядка исходного listWithDuplicates .

Если нам нужно сохранить порядок, мы можем вместо этого использовать LinkedHashSet :

public void 
givenListContainsDuplicates_whenRemovingDuplicatesPreservingOrderWithPlainJava_thenCorrect() {
List<Integer> listWithDuplicates = Lists.newArrayList(5, 0, 3, 1, 2, 3, 0, 0);
List<Integer> listWithoutDuplicates = new ArrayList<>(
new LinkedHashSet<>(listWithDuplicates));

assertThat(listWithoutDuplicates, hasSize(5));
assertThat(listWithoutDuplicates, containsInRelativeOrder(5, 0, 3, 1, 2));
}

3. Удалить дубликаты из списка с помощью гуавы

Мы можем сделать то же самое, используя Guava:

public void 
givenListContainsDuplicates_whenRemovingDuplicatesWithGuava_thenCorrect() {
List<Integer> listWithDuplicates = Lists.newArrayList(5, 0, 3, 1, 2, 3, 0, 0);
List<Integer> listWithoutDuplicates
= Lists.newArrayList(Sets.newHashSet(listWithDuplicates));

assertThat(listWithoutDuplicates, hasSize(5));
assertThat(listWithoutDuplicates, containsInAnyOrder(5, 0, 3, 1, 2));
}

Здесь также первоначальный список остается без изменений.

Опять же, порядок элементов в очищаемом списке может быть случайным.

Если мы используем реализацию LinkedHashSet , мы сохраним исходный порядок:

public void 
givenListContainsDuplicates_whenRemovingDuplicatesPreservingOrderWithGuava_thenCorrect() {
List<Integer> listWithDuplicates = Lists.newArrayList(5, 0, 3, 1, 2, 3, 0, 0);
List<Integer> listWithoutDuplicates
= Lists.newArrayList(Sets.newLinkedHashSet(listWithDuplicates));

assertThat(listWithoutDuplicates, hasSize(5));
assertThat(listWithoutDuplicates, containsInRelativeOrder(5, 0, 3, 1, 2));
}

4. Удаление дубликатов из списка с помощью Java 8 Lambdas

Наконец, давайте рассмотрим новое решение, использующее лямбда-выражения в Java 8. Мы будем использовать метод different () из Stream API, который возвращает поток, состоящий из отдельных элементов, на основе результата, возвращаемого методом equals() .

Кроме того, для упорядоченных потоков выбор отдельных элементов является стабильным . Это означает, что для повторяющихся элементов сохраняется элемент, появляющийся первым в порядке обнаружения:

public void 
givenListContainsDuplicates_whenRemovingDuplicatesWithJava8_thenCorrect() {
List<Integer> listWithDuplicates = Lists.newArrayList(5, 0, 3, 1, 2, 3, 0, 0);
List<Integer> listWithoutDuplicates = listWithDuplicates.stream()
.distinct()
.collect(Collectors.toList());

assertThat(listWithoutDuplicates, hasSize(5));
assertThat(listWithoutDuplicates, containsInAnyOrder(5, 0, 3, 1, 2));
}

Итак, у нас есть три быстрых способа удалить все повторяющиеся элементы из списка.

5. Вывод

В этой статье мы продемонстрировали, как легко удалить дубликаты из списка с помощью простой Java, Google Guava и Java 8.

Реализацию всех этих примеров и сниппетов можно найти в проекте GitHub . Это проект на основе Maven, поэтому его легко импортировать и запускать.