Есть список, состоящий из массивов ArrayList<int[]> list1;
.
И второй список поменьше ArrayList<int[]> list2;
.
Но чтобы сравнить, содержит ли список list1
в себе list2
, такая запись почему-то не работает:
list1.containsAll(list2);
всегда выдает false
, даже если заранее знать, что list1
содержит в себе list2
.
В чем может быть проблема?
Принцип работы метода collectionA.containsAll(collectionB)
состоит в следующем:
Для каждого элемента коллекции B происходит проверка на его принадлежность коллекции А.
Проверка эта заключается в следующем:
Берется один элемент B и в цикле сравнивается с каждым элементом коллекции А.
Причем сравнение идет с помощью метода equals
.
У вас в коллекциях содержатся массивы. У массивов метод equals
не переопределен. Таким образом, будет использоваться метод equals
от класса Object, который даст true
только в том случае, если обе ссылки будут ссылаться на один и тот же массив в памяти.
Это все равно, что сравнивать массивы через оператор ==
. В вашем случае в разных коллекциях у вас лежат разные массивы, которые никогда не дадут true
при вызове метода equals
Подозреваю, что Вас может не устроить логика работы метода containsAll()
по умолчанию.
Поэтому, предлагаю переопределить методы на те, которые Вам нужны по сути работы.
Ниже пример реализации своего сравнения ArrayList<int[]>
с логикой сравнения по значениям без учета последовательности.
Кстати, сам метод containsAll()
мы не переопределяем, т.к. его реализация в классе ArrayList
нас устраивает. То есть метод containsAll() вызывает последовательно метод contains() для каждого элемента списка. Соответственно нам нужно переопределить только метод contains(), чтобы добиться нужной нам логики работы.
Ниже класс MyArrayList
import java.util.*;
public class MyArrayList extends ArrayList<int[]> {
/*переопределяем метод 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<int[]> list1 = new MyArrayList();
List<int[]> list2 = new MyArrayList();
List<int[]> 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
.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Какие существуют виды рекламных бордов и как выбрать подходящий?
Зная имя пакета, хочу открыть информацию о приложении в настройках(где можно остановить приложение, стереть данные, удалить и тп
Получить значение метода onResponse в переменную
Пытаюсь загрузить 'bangogg' из папки assets с помощью AssetManager: