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

Пересечение двух списков в Java

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

1. Обзор

В этом уроке мы узнаем, как получить пересечение двух List s .

Как и многое другое, это стало намного проще благодаря внедрению потоков в Java 8 .

2. Пересечение двух списков строк

Давайте создадим два List s из String с некоторым пересечением — оба содержат дублирующиеся элементы:

List<String> list = Arrays.asList("red", "blue", "blue", "green", "red");
List<String> otherList = Arrays.asList("red", "green", "green", "yellow");

А теперь определим пересечение списков с помощью потоковых методов :

Set<String> result = list.stream()
.distinct()
.filter(otherList::contains)
.collect(Collectors.toSet());

Set<String> commonElements = new HashSet(Arrays.asList("red", "green"));

Assert.assertEquals(commonElements, result);

Во-первых, мы удаляем повторяющиеся элементы с разными . Затем мы используем фильтр для выбора элементов, которые также содержатся в otherList .

Наконец, мы преобразуем наш вывод с помощью Collector . Пересечение должно содержать каждый общий элемент только один раз. Порядок не должен иметь значения, поэтому toSet — самый простой выбор, но мы также можем использовать toList или другой метод сбора.

Дополнительные сведения см. в нашем руководстве по коллекторам Java 8 .

3. Пересечение списков пользовательских классов

Что, если наши List содержат не String , а экземпляры пользовательского класса, который мы создали? Ну, пока мы следуем соглашениям Java, решение с потоковыми методами будет прекрасно работать для нашего пользовательского класса.

Как метод contains решает, появляется ли конкретный объект в списке? На основе метода равных . Таким образом, мы должны переопределить метод equals и убедиться, что он сравнивает два объекта на основе значений соответствующих свойств.

Например, два прямоугольника равны, если их ширина и высота равны.

Если мы не переопределяем метод equals , наш класс использует реализацию equals родительского класса. В конце дня, вернее, в цепочке наследования выполняется метод equals класса Object . Тогда два экземпляра равны, только если они ссылаются на один и тот же объект в куче. ``

Для получения дополнительной информации о методе equals см. нашу статью о контрактах Java equals() и hashCode() .

4. Вывод

В этой быстрой статье мы увидели, как использовать потоки для вычисления пересечения двух списков. Есть много других операций, которые раньше были довольно утомительными, но довольно простыми, если мы знаем, как работать с Java Stream API. Взгляните на наши дальнейшие руководства с потоками Java здесь .

Примеры кода доступны на GitHub .