Ich habe zwei Sätze, A und B, vom gleichen Typ.
Ich muss herausfinden, ob A ein Element aus der Menge B enthält.
Was wäre der beste Weg, dies zu tun, ohne die Sets zu durchlaufen? Die Set-Bibliothek hat contains(object)
und containsAll(collection)
, aber nicht containsAny(collection)
.
Antworten:
Würde nicht
Collections.disjoint(A, B)
funktionieren? Aus der Dokumentation:Daher gibt die Methode zurück,
false
wenn die Sammlungen gemeinsame Elemente enthalten.quelle
Stream::anyMatch
Seit Java 8 können Sie verwenden
Stream::anyMatch
.quelle
anyMatch
wird alle Elemente streamen und allesetA
aufrufensetB.contains()
. Wenn für eines der Elemente "true" zurückgegeben wird, wird der Ausdruck als Ganzes als true ausgewertet. Hoffe das hat geholfen.Eine gute Möglichkeit, includesAny für Sets zu implementieren, ist die Verwendung von Guava Sets.intersection () .
containsAny
würde a zurückgebenboolean
, so sieht der Anruf aus wie:Dies gibt true zurück, wenn die Mengen disjunkt sind, andernfalls false. Die zeitliche Komplexität ist wahrscheinlich etwas besser als bei keepAll, da Sie kein Klonen durchführen müssen, um Änderungen an Ihrem ursprünglichen Satz zu vermeiden.
quelle
Apache Commons hat eine Methode
CollectionUtils.containsAny()
.quelle
Ich benutze org.apache.commons.collections.CollectionUtils
Das ist alles! Gibt true zurück, wenn sich mindestens ein Element in beiden Sammlungen befindet.
Einfach zu bedienen, und der Name der Funktion ist aussagekräftiger.
quelle
Verwendung
retainAll()
in der Set-Oberfläche. Diese Methode bietet einen Schnittpunkt von Elementen, die in beiden Mengen gemeinsam sind. Weitere Informationen finden Sie in den API-Dokumenten.quelle
retainAll
wahrscheinlich nicht helfen. Seine Implementierung inAbstractCollection
Iterationen.O(1)
im besten Fall Laufzeit, währendretainAll
etwas entlang der Linien eines hätteO(N)
(es wäre nur ein Satz von der Größe abhängig) Best-Case-Laufzeit.Ich würde empfehlen, ein
HashMap
aus Satz A zu erstellen und dann Satz B zu durchlaufen und zu überprüfen, ob sich ein Element von B in A befindet. Dies würdeO(|A|+|B|)
zeitlich ausgeführt (da es keine Kollisionen geben würde), währendretainAll(Collection<?> c)
esO(|A|*|B|)
rechtzeitig ausgeführt werden muss.quelle
Dafür gibt es eine etwas grobe Methode. Genau dann, wenn die A-Menge ein B-Element als den Aufruf enthält
ändert das A-Set. In dieser Situation gibt removeAll true zurück (wie in den Dokumenten zum Entfernen von all angegeben ). Aber wahrscheinlich möchten Sie das A-Set nicht ändern, damit Sie auf eine Kopie wie folgt reagieren können:
und der Rückgabewert ist wahr, wenn die Mengen nicht verschieden sind, das heißt, sie haben einen nicht leeren Schnittpunkt.
Siehe auch Apache Commons-Sammlungen
quelle
Sie können die RetainAll- Methode verwenden und den Schnittpunkt Ihrer beiden Sätze ermitteln.
quelle
retainAll
können, muss eine Kopie des Originalsets erstellt werden. Dann ist es effizienter zu verwenden,HashSet
wie von Zéychin vorgeschlagen .