Научитесь сравнивать два ArrayList в Java, чтобы узнать, содержат ли они одинаковые элементы. Если оба списка не равны, мы найдем разницу между списками. Мы также научимся находить общие и различные элементы в каждом списке.
Обратите внимание, что разница между двумя списками равна третьему списку, который содержит либо дополнительные элементы, либо отсутствующие элементы.
1. Сравнение двух списков на предмет равенства
1.1. Сортировать, затем сравнить
Следующая программа Java проверяет, равны ли два заданных списка. Чтобы проверить равенство, нам нужно отсортировать оба списка и сравнить оба списка с помощью метода equals().
Метод List.equals() возвращает значение true для двух экземпляров списка тогда и только тогда, когда:
- оба списка имеют одинаковый размер
- оба содержат одни и те же элементы в точно таком же порядке
ArrayList<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));ArrayList<String> equalList = new ArrayList<>(Arrays.asList("c", "b", "a"));ArrayList<String> diffList = new ArrayList<>(Arrays.asList("a", "b", "d")); //c and d are changedCollections.sort(list);Collections.sort(equalList);Assertions.assertTrue(list.equals(equalList));Collections.sort(diffList);Assertions.assertFalse(list.equals(diffList));
1.2 Использование коллекций Commons
Если у вас есть зависимость commons-collections4 в проекте, мы можем использовать API CollectionUtils.isEqualCollection(). Этот API сравнивает элементы из обоих списков, игнорируя порядок.
boolean result = CollectionUtils.isEqualCollection(firstList, secondList);
1.3 Сравнение списков в модульных тестах
Если мы проверяем равенство списков в модульных тестах, то рассмотрите возможность использования Matchers.containsInAnyOrder().
Assertions.assertThat(firstList, Matchers.containsInAnyOrder( secondList.toArray() ));
См. также: Утверждение двух равных списков, игнорирующих порядок
2. Сравните два списка — найдите дополнительные элементы
В следующих примерах мы найдем элементы, которые присутствуют в списке list1, но отсутствую в списке list2.
2.1. Обычная Java
Если два arraylist не равны и мы хотим узнать, какие дополнительные элементы есть в первом списке по сравнению со вторым, используйте метод removeAll(). Он удаляет все элементы второго списка из первого списка и оставляет только дополнительные элементы в первом списке.
ArrayList<String> listOne = new ArrayList<>(Arrays.asList("a", "b", "c", "d"));ArrayList<String> listTwo = new ArrayList<>(Arrays.asList("a", "b", "e", "f"));//additional items in listOnelistOne.removeAll(listTwo);System.out.println(listOne); //[c, d]
2.2 Использование потокового API
Мы можем перебрать элементы списка первого списка и выполнить поиск всех элементов во втором списке. Если элемент присутствует во втором списке, удалить его из первого списка. После потоковых операций собрать элементы в новый список.
List<String> listOfAdditionalItems = listOne.stream().filter(item -> !listTwo.contains(item)).toList();Assertions.assertTrue(CollectionUtils.isEqualCollection(List.of("c", "d"), listOfAdditionalItems));
2.3 Использование CollectionUtils.removeAll()
CollectionUtils.removeAll(list1, list2) возвращает коллекцию, содержащую все элементы в list1, которых нет в list2. Класс CollectionUtils является частью библиотеки Apache commons-collection4.
List<String> listOfAdditionalItems =(List<String>) CollectionUtils.removeAll(listOne, listTwo);Assertions.assertTrue(CollectionUtils.isEqualCollection(List.of("c", "d"), listOfAdditionalItems));
3. Сравните два списка — найдите недостающие элементы
Чтобы получить недостающие элементы в списке 1, которые присутствуют в списке 2, мы можем обратить решения в предыдущем разделе.
Решение с использованием чистого Java:
ArrayList<String> listOne = new ArrayList<>(Arrays.asList("a", "b", "c", "d"));ArrayList<String> listTwo = new ArrayList<>(Arrays.asList("a", "b", "e", "f"));//missing items in listOnelistTwo.removeAll(listOne);System.out.println(listTwo); //[e, f]
Решение с использованием API потока выглядит следующим образом:
List<String> listOfMissingItems = listTwo.stream().filter(item -> !listOne.contains(item)).toList();Assertions.assertTrue(CollectionUtils.isEqualCollection(List.of("e", "f"), listOfMissingItems));
Аналогично используйте CollectionUtils.removeAll() со списком, упорядоченным в обратном порядке.
List<String> listOfMissingItems =(List<String>) CollectionUtils.removeAll(listTwo, listOne);Assertions.assertTrue(CollectionUtils.isEqualCollection(List.of("e", "f"), listOfMissingItems));
4. Сравните два списка — найдите общие элементы
Чтобы найти общие элементы в двух arraylist, используйте метод List.retainAll(). Этот метод сохраняет только те элементы в этом списке, которые содержатся в указанном arraylist, переданном в качестве аргумента метода.
ArrayList<String> listOne = new ArrayList<>(Arrays.asList("a", "b", "c", "d"));ArrayList<String> listTwo = new ArrayList<>(Arrays.asList("a", "b", "e", "f"));//common items in listOne and listTwolistOne.retainAll(listTwo); //[a, b]
Мы можем использовать Stream API для поиска всех общих элементов следующим образом:
List<String> listOfCommonItems = listOne.stream().filter(item -> listTwo.contains(item)).toList();Assertions.assertTrue(CollectionUtils.isEqualCollection(List.of("a", "b"), listOfCommonItems));
Также можно использовать метод CollectionUtils.intersection(), который возвращает общие элементы в двух списках.
List<String> listOfCommonItems =(List<String>) CollectionUtils.intersection(listTwo, listOne);Assertions.assertTrue(CollectionUtils.isEqualCollection(List.of("a", "b"), listOfCommonItems));
Читать далее:
Руководство по Java ArrayList
ArrayList Java Документация