Перетин двох списків на Java

1. Огляд

У цьому підручнику ми дізнаємося, як отримати перетин двох списків .

Як і багато інших речей, це стало набагато простіше завдяки введенню потоків в Java 8.

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

Давайте створимо два список s з рядка s з деяким перетином - обидва мають деякі дубльовані елементи:

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

А тепер ми визначимо перетин списків за допомогою потокових методів :

Set result = list.stream() .distinct() .filter(otherList::contains) .collect(Collectors.toSet()); Set commonElements = new HashSet(Arrays.asList("red", "green")); Assert.assertEquals(commonElements, result);

По-перше, ми видаляємо дубльовані елементи чітко . Потім ми використовуємо фільтр для вибору елементів, які також містяться в otherList .

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

Щоб отримати докладнішу інформацію, перегляньте наш посібник із колекціонерів Java 8.

3. Перетин списків нестандартних класів

Що робити , якщо наш Список s не містить рядки s, а екземпляри користувальницького класу ми створили? Що ж, поки ми дотримуємося домовленостей Java, рішення з потоковими методами буде чудово працювати для нашого користувацького класу.

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

Наприклад, два прямокутники рівні, якщо їх ширина та висота рівні.

Якщо ми не замінюємо метод equals , наш клас використовує реалізацію equals батьківського класу. В кінці дня, а точніше, ланцюжок успадкування, виконується метод Object класу ' equals . Тоді два екземпляри рівні, лише якщо вони посилаються на абсолютно однаковий об'єкт у купі.

Для отримання додаткової інформації про метод equals див. Нашу статтю про контракти Java equals () та hashCode () .

4. Висновок

У цій короткій статті ми побачили, як використовувати потоки для обчислення перетину двох списків. Є багато інших операцій, які раніше були досить втомливими, але досить простими, якщо ми знаємо, як обійти API Java Stream. Погляньте на наші подальші підручники з потоками Java тут.

Приклади коду доступні на GitHub.