Mam dwie listy z różnymi obiektami.
List<Object1> list1;
List<Object2> list2;
Chcę sprawdzić, czy element z listy1 istnieje na liście2, na podstawie określonego atrybutu (Object1 i Object2 mają (między innymi) jeden wspólny atrybut (z typem Long) o nazwie attributeSame).
teraz robię to tak:
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;
}
Ale myślę, że jest na to lepszy i szybszy sposób :) Czy ktoś może to zaproponować?
Dzięki!
Odpowiedzi:
Jeśli potrzebujesz tylko przetestować podstawową równość, można to zrobić za pomocą podstawowego JDK bez modyfikowania list wejściowych w jednej linii
Jeśli chcesz przetestować określoną właściwość, jest to trudniejsze. Poleciłbym domyślnie
... który zbiera różne wartości
list2
wi testuje każdą wartość podlist1
kątem obecności.źródło
list1
do aSet
przed porównaniem, otrzymasz O (n) + O (m), to znaczy O (n + m), kosztem dodatkowej pamięci RAM; to kwestia wyboru między szybkością a pamięcią.Możesz użyć Apache Commons CollectionUtils :
Zakłada się, że poprawnie przeciążono funkcjonalność equals dla obiektów niestandardowych.
źródło
Aby skrócić logikę Narendry, możesz użyć tego:
źródło
list1.stream().anyMatch(list2::contains);
Jest jedna metoda o
Collection
nazwieretainAll
, ale o pewne skutki uboczne dla Ciebie odniesieniaTo jest jak
źródło
Odpowiedź Loiusa jest poprawna, chcę tylko dodać przykład:
źródło
szybszy sposób będzie wymagał dodatkowej przestrzeni.
Na przykład:
umieść wszystkie pozycje z jednej listy w HashSet (musisz samodzielnie zaimplementować funkcję hash, aby użyć object.getAttributeSame ())
Przejrzyj drugą listę i sprawdź, czy jakikolwiek element znajduje się w HashSet.
W ten sposób każdy obiekt odwiedzany jest najwyżej raz. a HashSet jest wystarczająco szybki, aby sprawdzić lub wstawić dowolny obiekt do O (1).
źródło
Według JavaDoc dla
.contains(Object obj)
:Więc jeśli nadpisujesz swoją
.equals()
metodę dla danego obiektu, powinieneś być w stanie zrobić:if(list1.contains(object2))...
Jeśli elementy będzie wyjątkowy (tzn. Mają różne atrybuty) można zastąpić
.equals()
i.hashcode()
i przechowywać wszystkoHashSets
. Pozwoli ci to sprawdzić, czy jeden zawiera inny element w stałym czasie.źródło
aby przyspieszyć, możesz dodać przerwę; w ten sposób pętla zatrzyma się, jeśli found ma wartość true:
Gdybyś miał mapy zamiast list z kluczami o nazwie Atrybut ten sam, możesz szybciej sprawdzić wartość na jednej mapie, czy na drugiej mapie jest odpowiednia wartość, czy nie.
źródło
Czy możesz zdefiniować rodzaj przechowywanych danych? czy to duże zbiory danych? czy to jest posortowane? Myślę, że w zależności od danych należy rozważyć różne podejścia do wydajności.
Na przykład, jeśli twoje dane są duże i nieposortowane, możesz spróbować iterować dwie listy razem według indeksu i przechowywać każdy atrybut listy w innym pomocniku list. następnie możesz sprawdzić bieżące atrybuty na listach pomocników.
powodzenia
redagowane: i nie polecałbym przeciążania równa się. jest to niebezpieczne i prawdopodobnie przeciwko twojemu przedmiotowi oop znaczenie.
źródło
org.springframework.util.CollectionUtils
źródło
Za pomocą
java 8
możemy zrobić jak poniżej, aby sprawdzić, czy jedna lista zawiera jakikolwiek element innej listyźródło
Jeśli chcesz sprawdzić, czy element istnieje na liście, użyj metody zawiera.
źródło