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, поэтому его легко импортировать и запускать.