Mam dwa zestawy A i B tego samego typu.
Muszę sprawdzić, czy A zawiera jakikolwiek element ze zbioru B.
Jaki byłby najlepszy sposób na zrobienie tego bez powtarzania zestawów? Biblioteka Set ma contains(object)
i containsAll(collection)
, ale nie ma containsAny(collection)
.
Odpowiedzi:
Nie
Collections.disjoint(A, B)
działałoby? Z dokumentacji:Zatem metoda zwraca,
false
jeśli kolekcje zawierają jakieś wspólne elementy.źródło
Stream::anyMatch
Od wersji Java 8 możesz używać
Stream::anyMatch
.źródło
anyMatch
przesyła strumieniowo wszystkie elementysetA
i wzywasetB.contains()
je wszystkie. Jeśli dla któregoś z elementów zostanie zwrócona wartość „prawda”, wyrażenie jako całość zostanie ocenione na wartość prawda. Mam nadzieję, że to pomogło.Dobrym sposobem na zaimplementowanie funkcji ZawieraDowolny dla zestawów jest użycie Guava Sets.intersection () .
containsAny
zwróci aboolean
, więc połączenie wygląda następująco:Zwraca true, jeśli zestawy są rozłączne, w przeciwnym razie false. Złożoność czasowa tego jest prawdopodobnie nieco lepsza niż zachowanie All, ponieważ nie trzeba wykonywać żadnego klonowania, aby uniknąć modyfikacji oryginalnego zestawu.
źródło
Apache Commons ma metodę
CollectionUtils.containsAny()
.źródło
Używam org.apache.commons.collections.CollectionUtils
To wszystko! Zwraca wartość true, jeśli co najmniej jeden element znajduje się w obu kolekcjach.
Prosty w użyciu, a nazwa funkcji jest bardziej sugestywna.
źródło
Użyj
retainAll()
w interfejsie Ustaw. Ta metoda zapewnia przecięcie elementów wspólnych w obu zestawach. Zobacz dokumentację API, aby uzyskać więcej informacji.źródło
retainAll
prawdopodobnie nie pomoże. Jego implementacja wAbstractCollection
iteracjach.O(1)
w najlepszym przypadku czas działania, podczas gdyretainAll
miałby coś wzdłuż liniiO(N)
(zależałoby to od wielkości tylko 1 zestawu) najlepszy czas działania.Poleciłbym utworzenie
HashMap
zestawu A, a następnie iterowanie przez zestaw B i sprawdzenie, czy którykolwiek element B znajduje się w A. To działałoby wO(|A|+|B|)
czasie (ponieważ nie byłoby kolizji), podczas gdyretainAll(Collection<?> c)
musiało działać wO(|A|*|B|)
czasie.źródło
Jest to nieco trudna metoda. Jeśli tylko zestaw A zawiera element B niż wywołanie
zmodyfikuje zestaw A. W tej sytuacji removeAll zwróci wartość true (jak stwierdzono w removeAll docs ). Ale prawdopodobnie nie chcesz modyfikować zestawu A, więc możesz pomyśleć o działaniu na kopię, w następujący sposób:
a zwracana wartość będzie prawdziwa, jeśli zbiory nie będą odrębne, to znaczy, że mają niepuste przecięcie.
Zobacz także Kolekcje Apache Commons
źródło
Możesz użyć metody retainAll i uzyskać przecięcie dwóch zbiorów.
źródło
retainAll
, należy wykonać kopię oryginalnego zestawu. Następnie jest bardziej wydajny w użyciu,HashSet
jak sugeruje Zéychin .