Tengo dos conjuntos, A y B, del mismo tipo.
Tengo que encontrar si A contiene algún elemento del conjunto B.
¿Cuál sería la mejor manera de hacerlo sin iterar sobre los conjuntos? La biblioteca Set tiene contains(object)
y containsAll(collection)
, pero no containsAny(collection)
.
Respuestas:
No
Collections.disjoint(A, B)
funcionaria? De la documentación:Por lo tanto, el método devuelve
false
si las colecciones contienen elementos comunes.fuente
Stream::anyMatch
Desde Java 8 podrías usar
Stream::anyMatch
.fuente
anyMatch
transmitirá todos los elementossetA
y los llamarásetB.contains()
a todos. Si se devuelve "verdadero" para cualquiera de los elementos, la expresión como un todo se evaluará como verdadera. Espero que esto haya ayudado.Una buena forma de implementar contieneAny para conjuntos es usar Guava Sets.intersection () .
containsAny
devolvería unboolean
, por lo que la llamada se ve así:Esto devuelve verdadero si los conjuntos son disjuntos, de lo contrario falso. La complejidad temporal de esto es probablemente un poco mejor que retener todo porque no tiene que hacer ninguna clonación para evitar modificar su conjunto original.
fuente
Apache Commons tiene un método
CollectionUtils.containsAny()
.fuente
Yo uso org.apache.commons.collections.CollectionUtils
¡Eso es todo! Devuelve verdadero si al menos un elemento está en ambas colecciones.
Simple de usar, y el nombre de la función es más sugerente.
fuente
Úselo
retainAll()
en la interfaz Set. Este método proporciona una intersección de elementos comunes en ambos conjuntos. Consulte los documentos de la API para obtener más información.fuente
retainAll
probablemente no ayudará. Su implementación enAbstractCollection
iteraciones.O(1)
tiempo de ejecución en el mejor de los casos, mientrasretainAll
que tendría algo similar a unO(N)
(dependería del tamaño de solo 1 conjunto) mejor tiempo de ejecución.Recomendaría crear un
HashMap
conjunto A y luego iterar a través del conjunto B y verificar si algún elemento de B está en A. Esto se ejecutaría aO(|A|+|B|)
tiempo (ya que no habría colisiones), mientras queretainAll(Collection<?> c)
debe ejecutarse aO(|A|*|B|)
tiempo.fuente
Hay un método un poco difícil para hacer eso. Si y solo si el conjunto A contiene algún elemento de B que la llamada
modificará el conjunto A. En esta situación, removeAll devolverá true (como se indica en removeAll docs ). Pero probablemente no desee modificar el conjunto A, por lo que puede pensar en actuar en una copia, de esta manera:
y el valor de retorno será verdadero si los conjuntos no son distintos, es decir, tienen una intersección no vacía.
Ver también Colecciones de Apache Commons
fuente
Puede usar el método retiene todos y obtener la intersección de sus dos conjuntos.
fuente
retainAll
es necesario hacer una copia del conjunto original. Entonces es más eficiente de usarHashSet
como lo sugiere Zéychin .