У меня есть два списка с разными объектами.
List<Object1> list1;
List<Object2> list2;
Я хочу проверить, существует ли элемент из списка1 в списке2 на основе определенного атрибута (Object1 и Object2 имеют (среди прочего) один общий атрибут (с типом Long) с именем attributeSame).
щас делаю вот так:
boolean found = false;
for(Object1 object1 : list1){
for(Object2 object2: list2){
if(object1.getAttributeSame() == object2.getAttributeSame()){
found = true;
//also do something
}
}
if(!found){
//do something
}
found = false;
}
Но я думаю, что есть лучший и более быстрый способ сделать это :) Может кто-нибудь предложить?
Спасибо!
Ответы:
Если вам просто нужно проверить базовое равенство, это можно сделать с помощью базового JDK без изменения списков ввода в одной строке
Если вам нужно протестировать конкретное свойство, это сложнее. Я бы рекомендовал по умолчанию
... который собирает различные значения
list2
и проверяет каждое значениеlist1
на наличие.источник
list1
в aSet
перед сравнением, вы получите O (n) + O (m), то есть O (n + m), за счет некоторой дополнительной RAM; это вопрос выбора между скоростью или памятью.Вы можете использовать Apache Commons CollectionUtils :
Это предполагает, что вы правильно перегрузили функцию равенства для своих настраиваемых объектов.
источник
Чтобы сократить логику Нарендры, вы можете использовать это:
источник
list1.stream().anyMatch(list2::contains);
Существует один метод с
Collection
именем named,retainAll
но с некоторыми побочными эффектами для справки.Это как
источник
Ответ Лойуса правильный, я просто хочу добавить пример:
источник
более быстрый способ потребует дополнительного места.
Например:
поместите все элементы в один список в HashSet (вы должны реализовать хэш-функцию самостоятельно, чтобы использовать object.getAttributeSame ())
Просмотрите другой список и проверьте, есть ли какой-либо элемент в HashSet.
Таким образом, каждый объект посещается не более одного раза. и HashSet достаточно быстр, чтобы проверить или вставить любой объект в O (1).
источник
Согласно JavaDoc для
.contains(Object obj)
:Итак, если вы переопределите свой
.equals()
метод для данного объекта, вы должны иметь возможность:if(list1.contains(object2))...
Если элементы будут уникальными (т. Е. Иметь разные атрибуты), вы можете переопределить
.equals()
и.hashcode()
и сохранить все вHashSets
. Это позволит вам проверить, содержит ли один другой элемент в постоянное время.источник
чтобы было быстрее, можно добавить перерыв; таким образом цикл остановится, если для параметра found установлено значение true:
Если бы у вас были карты вместо списков с ключами attributeSame, вы могли бы быстрее проверять значение на одной карте, есть ли соответствующее значение на второй карте или нет.
источник
Можете ли вы определить тип данных, которые вы храните? это большие данные? это отсортировано? Я думаю, что нужно учитывать разные подходы к эффективности в зависимости от данных.
Например, если ваши данные большие и несортированные, вы можете попытаться перебрать два списка вместе по индексу и сохранить каждый атрибут списка в другом помощнике списка. тогда вы можете перекрестно проверить текущие атрибуты в списках помощников.
удачи
отредактировал: и я бы не рекомендовал перегружать равные. это опасно и, вероятно, против вашего смысла объекта.
источник
org.springframework.util.CollectionUtils
источник
С помощью
java 8
мы можем сделать, как показано ниже, чтобы проверить, содержит ли один список какой-либо элемент другого списка.источник
Если вы хотите проверить, существует ли элемент в списке, используйте метод contains.
источник