Страницы

Поиск по вопросам

пятница, 13 декабря 2019 г.

Java. containsAll для списка массивов

#java


Есть список, состоящий из массивов ArrayList  list1;. 
И второй список поменьше ArrayList  list2;.

Но чтобы сравнить, содержит ли список list1 в себе list2, такая запись почему-то
не работает:

list1.containsAll(list2);


всегда выдает false, даже если заранее знать, что list1 содержит в себе list2.

В чем может быть проблема?
    


Ответы

Ответ 1



Принцип работы метода collectionA.containsAll(collectionB) состоит в следующем: Для каждого элемента коллекции B происходит проверка на его принадлежность коллекции А. Проверка эта заключается в следующем: Берется один элемент B и в цикле сравнивается с каждым элементом коллекции А. Причем сравнение идет с помощью метода equals. У вас в коллекциях содержатся массивы. У массивов метод equals не переопределен. Таким образом, будет использоваться метод equals от класса Object, который даст true только в том случае, если обе ссылки будут ссылаться на один и тот же массив в памяти. Это все равно, что сравнивать массивы через оператор ==. В вашем случае в разных коллекциях у вас лежат разные массивы, которые никогда не дадут true при вызове метода equals

Ответ 2



Подозреваю, что Вас может не устроить логика работы метода containsAll() по умолчанию. Поэтому, предлагаю переопределить методы на те, которые Вам нужны по сути работы. Ниже пример реализации своего сравнения ArrayList с логикой сравнения по значениям без учета последовательности. Кстати, сам метод containsAll() мы не переопределяем, т.к. его реализация в классе ArrayList нас устраивает. То есть метод containsAll() вызывает последовательно метод contains() для каждого элемента списка. Соответственно нам нужно переопределить только метод contains(), чтобы добиться нужной нам логики работы. Ниже класс MyArrayList import java.util.*; public class MyArrayList extends ArrayList { /*переопределяем метод contains(), потому что метод containsAll() будет вызывать метод contains() для каждого объекта списка ArrayList. */ @Override public boolean contains(Object o) { int[] arr = (int[])o; //сортируем входящий массив "o" по значениям. Arrays.sort(arr); //каждый объекта нашего списка "this" сравниваем с объектом "o". for (int[] i : this) { //сортируем выбранный массив "i" по значениям. Arrays.sort(i); //Сравниваем два массива "i" и "o" по содержимому. if(Arrays.toString(i).compareTo(Arrays.toString(arr)) == 0) { return true; } } /*если заданный отсортированный массив "o" не был найден ни в одном массиве списка "this", то contains()=false */ return false; } } Ниже класс Application для тестирования import java.util.*; public class Application { public static void main( String[] args ) { List list1 = new MyArrayList(); List list2 = new MyArrayList(); List list3 = new MyArrayList(); list1.add(new int[]{1, 2, 3}); list1.add(new int[]{9, 4, 5, 6}); list1.add(new int[]{4, 5, 6}); list2.add(new int[]{4, 5, 6}); list2.add(new int[]{1, 2, 3}); list3.add(new int[]{1, 2, 3}); list3.add(new int[]{4, 5, 55, 6}); System.out.println("containsAll() list2 in list1 = " + list1.containsAll(list2)); System.out.println("containsAll() list3 in list1 = " + list1.containsAll(list3)); } } Результат запуска этого примера ниже: containsAll() list2 in list1 = true containsAll() list3 in list1 = false Описание: То есть все отсортированные массивы в списке list2 содержатся в отсортированных массивах списка list1, поэтому наш переопределенный метод containsAll() вернул true. Но для list3 containsAll() вернул false, потому что не все отсортированные массивы в списке list3 содержатся в отсортированных массивах списка list1.

Комментариев нет:

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