Как сравнить два списка java
Перейти к содержимому

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

  • автор:

Утвердить два списка для равенства, игнорируя порядок в 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. Заключение

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

у меня есть два списка ArrayList которые заполняются автоматичиски, читая даные с name.txt и name1.txt файлов, с помощю BufferedReader. два списка могут быть разной длины. я их сранивал так:

String str =»»;
List result1 = new ArrayList(list);
result1.removeAll(array);
str += (» Новый: » + result1);

и этот код работает. Вопрос: есть ли другой способ это сделать чтобы я мог вывести весь список list и елементы которых нет в списке array были или другого цвета или шрифта просто как-то их выделить

  • Вопрос задан более двух лет назад
  • 420 просмотров

Как сравнить два списка 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

Списки на Java упорядочены по природе. Таким образом, два списка считаются равными, если они содержат одинаковые элементы в одинаковом порядке. В этом уроке мы увидим, как сравнить два списка на равенство в Java.

Мы также рассмотрим способы сравнения элементов в двух списках и игнорирования их порядка.

Порядок поддержания равенства списков:

Как мы знаем, два списка равны, когда они имеют одинаковые элементы и в одинаковом порядке. Поэтому, если мы заботимся о порядке, мы можем использовать метод equals () для проверки равенства:

public void equalityCheckOfTwoLists() < List list1 = Arrays.asList( 1 , 2 , 3 );
List list2 = Arrays.asList( 1 , 2 , 3 );
List list3 = Arrays.asList( 2 , 1 , 3 );
assertTrue(list1.equals(list2));
assertFalse(list1.equals(list3));

И list1, и list3 содержат одинаковые элементы , но в разных порядках и поэтому считаются неравными.

Порядок игнорирования равенства списков:

Что если мы хотим игнорировать порядок элементов для проверки на равенство?

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

1. Сортировка списков и сравнение:

Если оба списка нулевые , мы вернем true . Или же, если только один из них указывает на нулевое значение или размер () двух списков отличается, мы вернем false . Если ни одно из этих условий не выполняется, мы сначала отсортируем два списка, а затем сравним их:

public > boolean isEquals(List list1, List list2)
if (list1 == null && list2 == null ) < return true ; //Only one of them is null else if (list1 == null || list2 == null ) < return false ; else if (list1.size() != list2.size()) < return false ; //copying to avoid rearranging original lists list1 = new ArrayList(list1);
list2 = new ArrayList(list2);
Collections.sort(list1);
Collections.sort(list2);
return list1.equals(list2);

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

2. С помощью Set / содержит () Проверьте:

Если данные в наших списках уникальны, т.е. нет дублирования, мы можем просто создать TreeSets из заданных списков и затем сравнить их с помощью equals () :

public > boolean isEquals(List list1, List list2)
if (list1 == null && list2 == null ) < return true ; //Only one of them is null else if (list1 == null || list2 == null ) < return false ; else if (list1.size() != list2.size()) < return false ; Set set1 = new TreeSet<>(list1);
Set set2 = new TreeSet<>(list2);
return set1.equals(set2);

Мы можем еще больше упростить это, просто установив проверку на проверку содержимого () вместо создания наборов :

return list1.containsAll(list2) && list2.containsAll(list1);

Однако обратите внимание, что эти подходы ( contains () check / With Sets ) потерпят неудачу, если в нашем наборе данных есть повторы. Например:

List list1 = Arrays.asList( 1 , 2 , 3 , 3 );
List list2 = Arrays.asList( 3 , 1 , 2 , 2 );
// will return true, but actual value should be false
System.out.println(list1.isEquals(list2));

В приведенном выше примере l ist1 содержит одно 2 и два 3, а list2 содержит два 2 и одно 3 . Тем не менее, эта форма реализации будет неверно возвращать true .

3. Apache Commons:

Вместо написания собственного кода мы можем выбрать для выполнения утилиту Apache Commons Collections :

List list1 = Arrays.asList( 1 , 2 , 3 , 3 );
List list2 = Arrays.asList( 3 , 1 , 3 , 2 );
System.out.println(CollectionUtils.isEqualCollection(list1, list2)); //true

Метод isEqualCollection () возвращает true, если две коллекции содержат абсолютно одинаковые элементы с одинаковым количеством элементов.

Вывод:

В этом уроке мы научились проверять, равны ли два списка в Java. Теперь мы знаем, что по умолчанию два списка равны, если они имеют одинаковые элементы в одинаковом порядке.

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

Оставьте первый комментарий.

Опубликовано на Java Code Geeks с разрешения Шубхры Шриваставы, партнера нашей программы JCG . Смотрите оригинальную статью здесь: Проверьте, равны ли два списка в Java

Мнения, высказанные участниками Java Code Geeks, являются их собственными.

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

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