Утвердить два списка для равенства, игнорируя порядок в 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
List
List
assertTrue(list1.equals(list2));
assertFalse(list1.equals(list3));
И list1, и list3 содержат одинаковые элементы , но в разных порядках и поэтому считаются неравными.
Порядок игнорирования равенства списков:
Что если мы хотим игнорировать порядок элементов для проверки на равенство?
Много раз все, что мы хотим, это проверить, содержат ли два списка одинаковые элементы, независимо от их порядка в списке. Давайте рассмотрим способы достижения этого:
1. Сортировка списков и сравнение:
Если оба списка нулевые , мы вернем true . Или же, если только один из них указывает на нулевое значение или размер () двух списков отличается, мы вернем false . Если ни одно из этих условий не выполняется, мы сначала отсортируем два списка, а затем сравним их:
public
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
list2 = new ArrayList
Collections.sort(list1);
Collections.sort(list2);
return list1.equals(list2);
Обратите внимание, что мы создали копии двух списков, чтобы гарантировать, что элементы в исходных списках остаются нетронутыми .
2. С помощью Set / содержит () Проверьте:
Если данные в наших списках уникальны, т.е. нет дублирования, мы можем просто создать TreeSets из заданных списков и затем сравнить их с помощью equals () :
public
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
Set
return set1.equals(set2);
Мы можем еще больше упростить это, просто установив проверку на проверку содержимого () вместо создания наборов :
return list1.containsAll(list2) && list2.containsAll(list1);
Однако обратите внимание, что эти подходы ( contains () check / With Sets ) потерпят неудачу, если в нашем наборе данных есть повторы. Например:
List
List
// 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
List
System.out.println(CollectionUtils.isEqualCollection(list1, list2)); //true
Метод isEqualCollection () возвращает true, если две коллекции содержат абсолютно одинаковые элементы с одинаковым количеством элементов.
Вывод:
В этом уроке мы научились проверять, равны ли два списка в Java. Теперь мы знаем, что по умолчанию два списка равны, если они имеют одинаковые элементы в одинаковом порядке.
Мы также обсудили подходы, которые мы можем использовать для проверки равенства списков, если мы не заботимся о порядке элементов.
Оставьте первый комментарий.
Опубликовано на Java Code Geeks с разрешения Шубхры Шриваставы, партнера нашей программы JCG . Смотрите оригинальную статью здесь: Проверьте, равны ли два списка в Java
Мнения, высказанные участниками Java Code Geeks, являются их собственными.