Зарегистрируйтесь, чтобы продолжить обучение

Множественные операции над списками Java: Списки

Помимо рассмотренных операций над списком, есть набор операций, которые выполняются между двумя и более списками. Среди них:

  • Расширение одного списка элементами другого списка.
  • Поиск общих элементов в двух и более списках.
  • Поиск элементов, которые есть в одном списке, но нет в другом.
  • Поиск элементов, которые уникальны для двух списков

Рассмотрим некоторые из них, с которыми вы наверняка будете сталкиваться в реальной жизни.

Копирование списков

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

var items = new ArrayList<String>();
items.add("hexlet");
items.add("youtube");
// Тип можно не указывать, он выводится автоматически
var itemsCopy = new ArrayList<>(items);

В примере выше получилось два независимых списка. Изменение одного не приводит к изменениям другого. Но так происходит не всегда. Если список состоит из объектов, которые можно менять, тогда изменение объекта в одном списке, повлияет и на другой, так как копирование списков не копирует элементы списка.

var items = new ArrayList<User>();
items.add(/* пользователь */);
items.add(/* пользователь */);

var itemsCopy = new ArrayList<>(items);

// Изменение имени пользователя в одном списке
// Отражается на пользователе в другом,
// так как это один и тот же объект
items.get(0).setFirstName("Another Name");

Сравнение списков

Как и копирование обычно нужно в рамках каких-то других операций. В самом простом случае бывает нужно сравнить равенство двух списков между собой. Так как списки это объекты, мы не можем сравнивать их напрямую, в таком случае будут сравниваться ссылки. Для правильного сравнения понадобится метод equals()

var items1 = List.of("Sun", "Mars");
var items2 = List.of("Sun", "Mars");

if (items1 == items2) { // false
    System.out.println("==");
}
if (items1.equals(items2)) { // true
    System.out.println("equals");
};

Метод equals() проверяет не только совпадение элементов, но и их порядок.

Кроме полного сопоставления, мы можем проверять вхождение одного списка в другой:

var items1 = List.of("Sun", "Mars", "Moon");
var items2 = List.of("Sun", "Mars");

items1.containsAll(items2); // true
items2.containsAll(items1); // false

Слияние списков

Операция выполняется с помощью метода addAll(), который добавляет в коллекцию поэлементно другую коллекцию, переданную как параметр. Этот метод меняет исходную коллекцию:

var items1 = new ArrayList<String>();
items1.add("Sun");
items1.add("Mars");

var items2 = new ArrayList<String>();
items2.add("Uranus");
items2.add("Saturn");

items1.addAll(items2); // добавляем items2 в items1
System.out.println(items1); // => [Sun, Mars, Uranus, Saturn]

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

var items1 = new ArrayList<String>();
items1.add("Sun");
items1.add("Mars");

var items2 = new ArrayList<String>();
items2.add("Uranus");
items2.add("Saturn");

var items3 = new ArrayList<>(items1);
// item1 и item2 не меняются
items3.addAll(items2); // добавляем items2 в items3
System.out.println(items3); // => [Sun, Mars, Uranus, Saturn]

Объединение списков

Операция объединения списков отличается от операции слияния. Объединение подразумевает то, что если элементы присутствуют в обоих списках, в результирующий список они попадут лишь в одном экземпляре. Подобная операция реализуется с помощью CollectionUtils.union()

var items1 = new ArrayList<String>();
items1.add("Sun");
items1.add("Mars");
items1.add("Uranus");

var items2 = new ArrayList<String>();
items2.add("Uranus");
items2.add("Saturn");

// Объединение меняет порядок элементов
var items3 = CollectionUtils.union(items1, items2);
System.out.println(items3); // => [Mars, Saturn, Uranus, Sun]

Пересечение списков

Под пересечением понимается поиск общих элементов, то есть тех, которые есть и в первом, и во втором списке. Пересечение выполняется с помощью метода retainAll(). Этот метод меняет исходную коллекцию.

var items1 = new ArrayList<String>();
items1.add("Sun");
items1.add("Uranus");
items1.add("Mars");

var items2 = new ArrayList<String>();
items2.add("Uranus");
items2.add("Saturn");

items1.retainAll(items2);
System.out.println(items1); // => [Uranus]

Если исходные коллекции должны остаться в неизменном виде, то снова поможет копирование списков.

var items1 = new ArrayList<String>();
items1.add("Sun");
items1.add("Uranus");
items1.add("Mars");

var items2 = new ArrayList<String>();
items2.add("Uranus");
items2.add("Saturn");

var items3 = new ArrayList<>(items1);
items3.retainAll(items2);
System.out.println(items3); // => [Uranus]

То же самое с использованием CollectionUtils.intersection()

// Не нужно создавать третий список
var items3 = CollectionUtils.intersection(items1, items2);
System.out.println(items3); // => [Uranus]

Разность списков

Под разностью понимается коллекция, состоящая из элементов первой коллекции, которых нет во второй. Java не предоставляет метода для решения этой задачи, поэтому у нас есть два варианта, либо реализовывать эту логику самостоятельно на циклах, либо воспользоваться CollectionUtils.subtract().

var items1 = new ArrayList<String>();
items1.add("Sun");
items1.add("Uranus");
items1.add("Mars");

var items2 = new ArrayList<String>();
items2.add("Uranus");
items2.add("Saturn");

var items3 = CollectionUtils.subtract(items1, items2);
System.out.println(items3); // => [Sun, Mars]

Дополнительные материалы

  1. Класс CollectionUtils — содержит утилитные методы для работы с Java коллекциями
  2. Метод списков retainAll()

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
Программирование на Java, Разработка веб-приложений и микросервисов используя Spring Boot, проектирование REST API
10 месяцев
с нуля
Старт 26 декабря

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»