Tenho duas listas com objetos diferentes.
List<Object1> list1;
List<Object2> list2;
Quero verificar se o elemento da lista1 existe na lista2, com base no atributo específico (Object1 e Object2 têm (entre outros), um atributo mútuo (com tipo Long), denominado attributeSame).
agora, eu faço assim:
boolean found = false;
for(Object1 object1 : list1){
for(Object2 object2: list2){
if(object1.getAttributeSame() == object2.getAttributeSame()){
found = true;
//also do something
}
}
if(!found){
//do something
}
found = false;
}
Mas acho que existe uma maneira melhor e mais rápida de fazer isso :) Alguém pode sugerir?
Obrigado!
Respostas:
Se você precisa apenas testar a igualdade básica, isso pode ser feito com o JDK básico sem modificar as listas de entrada em uma linha
Se você precisa testar uma propriedade específica, isso é mais difícil. Eu recomendaria, por padrão,
... que coleta os valores distintos
list2
e testa cada valor emlist1
quanto à presença.fonte
list1
em aSet
antes de comparar, obterá O (n) + O (m), ou seja, O (n + m), ao custo de um pouco de RAM extra; é uma questão de escolher entre velocidade ou memória.Você pode usar Apache Commons CollectionUtils :
Isso pressupõe que você sobrecarregou adequadamente a funcionalidade equals para seus objetos personalizados.
fonte
Para encurtar a lógica de Narendra, você pode usar isto:
fonte
list1.stream().anyMatch(list2::contains);
Existe um método de
Collection
nomeação,retainAll
mas tendo alguns efeitos colaterais para sua referênciaÉ como
fonte
A resposta do Loius está correta, só quero adicionar um exemplo:
fonte
maneira mais rápida exigirá espaço adicional.
Por exemplo:
coloque todos os itens em uma lista em um HashSet (você deve implementar a função hash sozinho para usar object.getAttributeSame ())
Percorra a outra lista e verifique se algum item está no HashSet.
Desta forma, cada objeto é visitado no máximo uma vez. e o HashSet é rápido o suficiente para verificar ou inserir qualquer objeto em O (1).
fonte
De acordo com o JavaDoc para
.contains(Object obj)
:Portanto, se você substituir seu
.equals()
método para o objeto fornecido, deverá ser capaz de fazer:if(list1.contains(object2))...
Se os elementos será único (ie. Tem atributos diferentes), você poderia substituir o
.equals()
e.hashcode()
e armazenar tudo emHashSets
. Isso permitirá que você verifique se um contém outro elemento em tempo constante.fonte
para torná-lo mais rápido, você pode adicionar uma pausa; dessa forma, o loop irá parar se encontrado for definido como verdadeiro:
Se você tivesse mapas em vez de listas com como chaves o attributeSame, você poderia verificar mais rapidamente se há um valor em um mapa se há um valor correspondente no segundo mapa ou não.
fonte
Você pode definir o tipo de dados que mantém? é big data? está classificado? Acho que você precisa considerar diferentes abordagens de eficiência, dependendo dos dados.
Por exemplo, se seus dados forem grandes e não classificados, você pode tentar iterar as duas listas juntas por índice e armazenar cada atributo de lista em outro auxiliar de lista. então você pode verificar os atributos atuais nas listas auxiliares.
boa sorte
editado: e eu não recomendaria sobrecarregar iguais. é perigoso e provavelmente contra o significado do objeto oop.
fonte
org.springframework.util.CollectionUtils
fonte
Com
java 8
, podemos fazer o seguinte para verificar se uma lista contém algum elemento de outra listafonte
Se você quiser verificar se um elemento existe em uma lista, use o método contains.
fonte