Eu tenho dois conjuntos, A e B, do mesmo tipo.
Eu tenho que descobrir se A contém algum elemento do conjunto B.
Qual seria a melhor maneira de fazer isso sem percorrer os sets? A biblioteca Set possui contains(object)
e containsAll(collection)
, mas não containsAny(collection)
.
Respostas:
Não
Collections.disjoint(A, B)
funcionaria? A partir da documentação:Portanto, o método retornará
false
se as coleções contiverem elementos comuns.fonte
Stream::anyMatch
Desde o Java 8 você pode usar
Stream::anyMatch
.fonte
anyMatch
transmitirá todos os elementossetA
e os chamarásetB.contains()
. Se "true" for retornado para qualquer um dos elementos, a expressão como um todo será avaliada como true. Espero que isso tenha ajudado.Uma boa maneira de implementar o containsAny para conjuntos é usar o Guava Sets.intersection () .
containsAny
retornaria umboolean
, para que a chamada se pareça com:Isso retorna true se os conjuntos forem disjuntos, caso contrário, false. A complexidade de tempo disso é provavelmente um pouco melhor que reterAll, porque você não precisa fazer nenhuma clonagem para evitar modificar seu conjunto original.
fonte
O Apache Commons possui um método
CollectionUtils.containsAny()
.fonte
Eu uso org.apache.commons.collections.CollectionUtils
Isso é tudo! Retorna true se pelo menos um elemento estiver nas duas coleções.
Simples de usar, e o nome da função é mais sugestivo.
fonte
Use
retainAll()
na interface Set. Este método fornece uma interseção de elementos comuns nos dois conjuntos. Consulte os documentos da API para obter mais informações.fonte
retainAll
provavelmente não ajudará. Sua implementaçãoAbstractCollection
itera.O(1)
tempo de execução no melhor dos casos, enquantoretainAll
teria algo ao longo das linhas de umO(N)
(isso dependeria do tamanho de apenas 1 conjunto) melhor tempo de execução.Eu recomendaria criar um a
HashMap
partir do conjunto A e, em seguida, percorrer o conjunto B e verificar se algum elemento de B está em A. Isso seria executado noO(|A|+|B|)
tempo (como não haveria colisões), enquantoretainAll(Collection<?> c)
deve ser executado noO(|A|*|B|)
tempo.fonte
Existe um método um pouco difícil de fazer isso. Se e somente se o conjunto A contiver algum elemento de B, a chamada
irá modificar o conjunto A. Nesta situação, removeAll retornará true (conforme indicado em removeAll docs ). Mas provavelmente você não deseja modificar o conjunto A para pensar em agir em uma cópia, assim:
e o valor retornado será verdadeiro se os conjuntos não forem distintos, ou seja, com interseção não vazia.
Veja também as coleções do Apache Commons
fonte
Você pode usar o método reterAll e obter a interseção de seus dois conjuntos.
fonte
retainAll
lo, é necessário fazer uma cópia do conjunto original. Então é mais eficiente usarHashSet
como sugerido por Zéychin .