Qualcosa come “contiene qualsiasi” per Java set?

Ho due serie, A e B, dello stesso tipo.

Devo trovare se A contiene un elemento del set B.

Quale sarebbe il modo migliore per farlo senza scorrere sui set? La libreria Set contains(object) e containsAll(collection) Tutto containsAll(collection) , ma non containsAny(collection) .

Collections.disjoint(A, B) funzionerebbe? Dalla documentazione:

Restituisce true se le due raccolte specificate non hanno elementi in comune.

Pertanto, il metodo restituisce false se le raccolte contengono elementi comuni.

Da Java 8: setA.stream().anyMatch(setB::contains)

Un buon modo per implementare contiene Any per set sta usando Guava Sets.intersection () .

containsAny restituirebbe un valore boolean , quindi la chiamata ha il seguente aspetto:

 Sets.intersection(set1, set2).isEmpty() 

Questo restituisce true se gli insiemi sono disgiunti, altrimenti falso. La complessità temporale di questo è probabilmente leggermente migliore di retainAll perché non è necessario eseguire alcuna clonazione per evitare di modificare il set originale.

Apache Commons ha un metodo CollectionUtils.containsAny() .

Usa retainAll() nell’interfaccia Set. Questo metodo fornisce un’intersezione di elementi comuni in entrambi gli insiemi. Vedi i documenti API per maggiori informazioni.

Uso org.apache.commons.collections.CollectionUtils

 CollectionUtils.containsAny(someCollection1, someCollection2) 

Questo è tutto! Restituisce true se almeno un elemento è in entrambe le raccolte.

Semplice da usare e il nome della funzione è più suggestivo.

È ansible utilizzare il metodo retainAll e ottenere l’intersezione dei due set.

Consiglierei di creare una HashMap dal set A, e quindi di scorrere l’insieme B e controllare se qualche elemento di B è in A. Questo sarebbe eseguito in O(|A|+|B|) tempo (dato che non ci sarebbero collisioni) , mentre retainAll(Collection c) deve essere eseguito nel tempo O(|A|*|B|) .

C’è un metodo un po ‘approssimativo per farlo. Se e solo se il set A contiene un elemento di B diverso dalla chiamata

 A.removeAll(B) 

modificherà il set A. In questa situazione, removeAll restituirà true (come indicato in removeAll docs ). Ma probabilmente non vuoi modificare il set A in modo che tu possa pensare di agire su una copia, in questo modo:

 new HashSet(A).removeAll(B) 

e il valore restituito sarà vero se gli insiemi non sono distinti, cioè hanno un’intersezione non vuota.

Vedi anche Apache Commons Collections