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

Как сравнить две коллекции java

  • автор:

Как сравнить два списка java

Чтобы сравнить два списка в Java , можно использовать метод equals() из класса java.util.List . Этот метод сравнивает содержимое двух списков.

import java.util.Arrays; import java.util.List; public class ListComparisonExample  public static void main(String[] args)  // Создаем два списка ListInteger> list1 = Arrays.asList(1, 2, 3); ListInteger> list2 = Arrays.asList(1, 2, 3); // Сравниваем два списка if (list1.equals(list2))  System.out.println("Списки равны"); > else  System.out.println("Списки не равны"); > > > 

В этом примере списки list1 и list2 содержат одни и те же элементы в том же порядке, поэтому метод equals() вернет true

Java. ArrayList. Сравнить содержимое двух листов без учета последовательности

Необходим метод выясняющий равны ли значения их ячеек без учета их порядка и последовательности то есть эти можно считать равными = true; Имея в виду что таких элементов может быть и много. Можно использовать любые фичи кроме фраимворков. Может есть короткий способ, наверняка сан предусмотрел такое дело. Может кто знает?

Отслеживать
задан 8 ноя 2016 в 11:44
5,327 11 11 золотых знаков 58 58 серебряных знаков 117 117 бронзовых знаков
containsAll(Collection c) пробовали?
8 ноя 2016 в 11:48

@MrFylypenko если у второго списка, например, убрать один из «a» (например последний), то containsAll покажет true все равно

8 ноя 2016 в 11:54
Не знал про этот метод спасибо!
8 ноя 2016 в 11:55

@АлексейШиманский верно, покажет true, но он не будет сортировать массивы и надеюсь решит поставленные задачи. Ваш вариант мне тоже нравится.

Утвердить два списка для равенства, игнорируя порядок в Java

Иногда при написании модульных тестов нам нужно сделать независимое от порядка сравнение списков. В этом коротком руководстве мы рассмотрим различные примеры написания таких модульных тестов.

2. Настройка​

Согласно документации Java List#equals , два списка равны, если они содержат одни и те же элементы в одном и том же порядке. Следовательно, мы не можем просто использовать метод equals , так как мы хотим выполнять независимое от порядка сравнение.

В этом руководстве мы будем использовать эти три списка в качестве примеров входных данных для наших тестов:

 List first = Arrays.asList(1, 3, 4, 6, 8);   List second = Arrays.asList(8, 1, 6, 3, 4);   List third = Arrays.asList(1, 3, 3, 6, 6); 

Существуют разные способы сравнения независимо от порядка. Давайте посмотрим на них один за другим.

3. Использование JUnit​

JUnit — это хорошо известная платформа, используемая для модульного тестирования в экосистеме Java.

Мы можем использовать приведенную ниже логику, чтобы сравнить равенство двух списков, используя методы assertTrue и assertFalse .

Здесь мы проверяем размер обоих списков и проверяем, содержит ли первый список все элементы второго списка и наоборот. Хотя это решение работает, оно не очень читабельно. Итак, теперь давайте рассмотрим некоторые альтернативы:

 @Test   public void whenTestingForOrderAgnosticEquality_ShouldBeTrue()    assertTrue(first.size() == second.size() && first.containsAll(second) && second.containsAll(first));   > 

В этом первом тесте размер обоих списков сравнивается, прежде чем мы проверяем, совпадают ли элементы в обоих списках. Поскольку оба этих условия возвращают значение true, наш тест будет пройден.

Давайте теперь посмотрим на неудачный тест:

 @Test   public void whenTestingForOrderAgnosticEquality_ShouldBeFalse()    assertFalse(first.size() == third.size() && first.containsAll(third) && third.containsAll(first));   > 

Напротив, в этой версии теста, хотя размер обоих списков одинаков, все элементы не совпадают.

4. Использование AssertJ​

AssertJ — это управляемая сообществом библиотека с открытым исходным кодом, используемая для написания плавных и насыщенных утверждений в тестах Java.

Чтобы использовать его в нашем проекте maven, давайте добавим зависимость assertj-core в файл pom.xml :

 dependency>   groupId>org.assertjgroupId>   artifactId>assertj-coreartifactId>   version>3.16.1version>   dependency> 

Давайте напишем тест для сравнения равенства двух экземпляров списка одного и того же элемента и одного размера:

 @Test   void whenTestingForOrderAgnosticEqualityBothList_ShouldBeEqual()    assertThat(first).hasSameElementsAs(second);   > 

В этом примере мы сначала проверяем, что содержит все элементы данной итерации и ничего больше, в любом порядке. Основным ограничением этого подхода является то, что метод hasSameElementsAs игнорирует дубликаты.

Давайте посмотрим на это на практике, чтобы понять, что мы имеем в виду:

 @Test   void whenTestingForOrderAgnosticEqualityBothList_ShouldNotBeEqual()    List a = Arrays.asList("a", "a", "b", "c");   List b = Arrays.asList("a", "b", "c");   assertThat(a).hasSameElementsAs(b);   > 

В этом тесте, хотя у нас одинаковые элементы, размер обоих списков не равен, но утверждение все равно будет верным, так как оно игнорирует дубликаты. Чтобы это работало, нам нужно добавить проверку размера для обоих списков:

 assertThat(a).hasSize(b.size()).hasSameElementsAs(b); 

Добавление проверки размера обоих наших списков с последующим методом hasSameElementsAs действительно завершится ошибкой, как и ожидалось.

5. Использование хамкреста​

Если мы уже используем Hamcrest или хотим использовать его для написания модульных тестов, вот как мы можем использовать метод Matchers#containsInAnyOrder для независимого от порядка сравнения.

Чтобы использовать Hamcrest в нашем проекте maven, давайте добавим зависимость hamcrest-all в файл pom.xml :

 dependency>   groupId>org.hamcrestgroupId>   artifactId>hamcrest-allartifactId>   version>1.3version>   dependency> 
 @Test   public void whenTestingForOrderAgnosticEquality_ShouldBeEqual()    assertThat(first, Matchers.containsInAnyOrder(second.toArray()));   > 

Здесь метод containsInAnyOrder создает независимый от порядка сопоставитель для Iterables , который выполняет сопоставление с проверяемыми элементами Iterable . Этот тест сопоставляет элементы двух списков, игнорируя порядок элементов в списке.

К счастью, это решение не страдает от той же проблемы, которая описана в предыдущем разделе, поэтому нам не нужно явно сравнивать размеры.

6. Использование Apache Commons​

Другой библиотекой или фреймворком помимо JUnit, Hamcrest или AssertJ, который мы можем использовать, является Apache CollectionUtils . Он предоставляет служебные методы для общих операций, которые охватывают широкий спектр вариантов использования и помогают нам избежать написания стандартного кода.

Чтобы использовать его в нашем проекте maven, добавим зависимость commons-collections4 в файл pom.xml :

 dependency>   groupId>org.apache.commonsgroupId>   artifactId>commons-collections4artifactId>   version>4.4version>   dependency> 

Вот тест с использованием CollectionUtils :

 @Test   public void whenTestingForOrderAgnosticEquality_ShouldBeTrueIfEqualOtherwiseFalse()    assertTrue(CollectionUtils.isEqualCollection(first, second));   assertFalse(CollectionUtils.isEqualCollection(first, third));   > 

Метод isEqualCollection возвращает значение true , если заданные коллекции содержат точно такие же элементы с одинаковым количеством элементов . В противном случае возвращается false .

7. Заключение​

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

Все эти примеры можно найти на GitHub .

  • 1. Обзор
  • 2. Настройка
  • 3. Использование JUnit
  • 4. Использование AssertJ
  • 5. Использование хамкреста
  • 6. Использование Apache Commons
  • 7. Заключение

Как сравнить две коллекции java

Как всегда сбалансированные задачи!) Где надо подгорает, где надо сами разберёмся) Заставляет думать и искать, всё как в жизни!

Nikolai Уровень 13
23 декабря 2023
ВНИМАНИЕ. Для задачи про hashCode() вам нужно прочитать лекцию hashCode() and equals()
Anastasia Уровень 14
20 декабря 2023

За 11 уровней, которые я прошла это была самая сложная статья. Разбирала ее 2 дня, мб кому поможет, вот что я поняла для себя: В java есть 4 метода сравнения: Сравнение по адресу == (для цифр) Сравнение по содержимому equals (для строк, текста), Сравнение по проверке через pool (только для текста, работает быстрее чем equals) Сравнение по хэш коду(для объектов, быстрое, но не качественное, вроде как) По содержимому сравнивает equals только строки (String), а если мы создали 2 или больше обьектов и хотим их сравнить, то equals будет их сравнивать как ==, те адрес, а не содержимое, как у String. Поэтому основной посыл, это если мы хотим сравнить 2 обьекта, нам нужно прописать руками методику работы equals. Короче надо просто зазубрить 4 вида кода выше и понять, что каждый из них делает: 1 вариант: Это тот обьект или другой? (код проверяет ссылки ==) 2 вариант. Ссылка обьекта пустая или нет(код проверяет null. Null это аналог 0, но для строк). 3 вариант. Равны ли 2 обьекта из разных классов? (код проверяет названия классов, в которых лежат обьекты(?) через метод getClass или instaseof). 4 вариант. Проверяет содержимое 2 обьектов, что внутри них. Тут нужно сделать приведение типов и потом вручную проверить переменные обоих классов через оператор this + если переменные строки, дополнительно написать еще слово equals и провести проверку на null. Я до конца не уверенна, что это 100% правильно, но как смогла понять((

Валерия Коновалова Уровень 13
19 декабря 2023
А в третьей задаче получается в правильном решении контракт нарушили? непорядок !
Kirill Cheremnykh Уровень 13
17 декабря 2023

В 4 пункте, зачем операция приведения типа «Person person = (Person) obj;», если мы только что проверили, что obj не является не типом Person? Получается, obj уже типа Person? или я что-то не понимаю

Evgeny Makarov Уровень 13
13 декабря 2023

public boolean equals(Object obj) < if (this == obj) return true; остальной код метода equals >А где почитать про this, который сам по себе, а не this.a или this.b?

Louis d’Ipinaisse Уровень 14
12 декабря 2023
для тех кто как и я не понял, в чем разница между

 Object.equals(obj_1, obj_2) 
 obj_1.equals(obj_2) 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *