Existem métodos para fazer isso? Eu estava procurando, mas não consegui encontrar nenhum.
Outra pergunta: preciso desses métodos para filtrar arquivos. Alguns são AND
filtros e outros são OR
filtros (como na teoria dos conjuntos), então eu preciso filtrar de acordo com todos os arquivos e o ArrayLists de união / interseção que contém esses arquivos.
Devo usar uma estrutura de dados diferente para armazenar os arquivos? Existe algo mais que ofereça um tempo de execução melhor?
java
list
union
intersection
yotamoo
fonte
fonte
Vector
? Essa classe foi desencorajada desde o Java 1.2.Vector
é para interações entre threads, mas também existem estruturas de dados mais seguras para esses casos de uso. Veja também esta questão . Qualquer biblioteca que aindaVector
esteja usando em 2016 é muito suspeita na minha opinião.Respostas:
Aqui está uma implementação simples, sem usar nenhuma biblioteca de terceiros. Principal vantagem
retainAll
,removeAll
eaddAll
é que esses métodos não modifique a entrada de listas original para os métodos.fonte
HashSet
paraintersection
que o desempenho médio do caso seja O (n) em vez de O (n ^ 2).Collection (também ArrayList):
Use uma implementação de lista, se você aceitar repetições, e uma implementação de conjunto, se não:
fonte
HashSet
.addAll()
é a união para listas; é apenas concatenar a segunda lista no final da primeira. Uma operação de união evitaria adicionar um elemento se a primeira lista já o contiver.Este post é bastante antigo, mas foi o primeiro a aparecer no google ao procurar esse tópico.
Eu quero fazer uma atualização usando fluxos Java 8 fazendo (basicamente) a mesma coisa em uma única linha:
Se alguém tiver uma solução melhor / mais rápida, avise-me, mas essa solução é uma ótima opção que pode ser facilmente incluída em um método sem adicionar uma classe / método auxiliar desnecessário e ainda assim manter a legibilidade.
fonte
Set
e use ocontains
método do conjunto . Nem tudo na vida tem que ser feito com correntes.união será
removeAll
e entãoaddAll
.Encontre mais na documentação da coleção (ArrayList é uma coleção) http://download.oracle.com/javase/1.5.0/docs/api/java/util/Collection.html
fonte
retainAll()
eremoveAll()
são operações O (n ^ 2) nas listas. Nós podemos fazer melhor.retainAll
de {1, 2, 2, 3, 4, 5} acima de {1, 2, 3} resulta em {1, 2, 2, 3}. Não deveria ser {1, 2, 3} o cruzamento?Uniões e interseções definidas apenas para conjuntos, não listas. Como você mencionou.
Verifique a biblioteca da goiaba para obter filtros A goiaba também fornece interseções e uniões reais
fonte
Você pode usar
CollectionUtils
do apache commons .fonte
A solução marcada não é eficiente. Tem uma complexidade de tempo O (n ^ 2). O que podemos fazer é classificar as duas listas e executar um algoritmo de interseção como o abaixo.
Este possui uma complexidade de O (n log n + n) que está em O (n log n). A união é feita de maneira semelhante. Apenas certifique-se de fazer as modificações adequadas nas instruções if-elseif-else.
Você também pode usar iteradores, se quiser (eu sei que eles são mais eficientes em C ++, não sei se isso também é verdade em Java).
fonte
contains()
um loop (como sugere Devenv) levaria tempo O (n + m). A classificação é desnecessariamente complicada e leva tempo O (n log n + m log n + n). Concedido que reduz o tempo O (n log n), mas ainda é pior que o tempo linear e muito mais complexo.Eu acho que você deve usar a
Set
para armazenar os arquivos, se quiser fazer uma interseção e união neles. Então você pode usar goiaba 's conjuntos de classe para fazerunion
,intersection
e filtrar por umPredicate
bem. A diferença entre esses métodos e as outras sugestões é que todos esses métodos criam vistas preguiçosas da união, interseção etc. dos dois conjuntos. O Apache Commons cria uma nova coleção e copia os dados para ela.retainAll
altera uma de suas coleções removendo elementos dela.fonte
Aqui está uma maneira de fazer uma interseção com fluxos (lembre-se de que você deve usar o java 8 para fluxos):
Um exemplo para listas com tipos diferentes. Se você tem uma noção entre foo e bar e pode obter um objeto de barra de foo, pode modificar seu fluxo:
fonte
Achei o ListUtils muito útil para este caso de uso.
Use ListUtils em org.apache.commons.collections se você não deseja modificar a lista existente.
ListUtils.intersection(list1, list2)
fonte
Você pode usar o commons-collections4 CollectionUtils
fonte
No Java 8, eu uso métodos auxiliares simples como este:
fonte
Se os objetos na lista são hasháveis (ou seja, possuem um hashCode decente e uma função igual), a abordagem mais rápida entre as tabelas aprox. size> 20 é construir um HashSet para a maior das duas listas.
fonte
Eu também estava trabalhando em uma situação semelhante e cheguei aqui em busca de ajuda. Acabei encontrando minha própria solução para Arrays. ArrayList AbsentDates = new ArrayList (); // Armazenará Array1-Array2
Nota: Publique isso se puder ajudar alguém a acessar esta página para obter ajuda.
fonte
Interseção de duas listas de objetos diferentes com base na chave comum - Java 8
fonte
JDK8 + (provavelmente o melhor desempenho)
Se você não se importa com o desempenho e prefere um código menor, basta usar:
fonte
Solução final:
fonte
Primeiro, estou copiando todos os valores de matrizes em uma única matriz e removendo valores duplicados na matriz. Linha 12, explicando se o mesmo número ocorre mais do que o tempo, coloque algum valor extra de lixo na posição "j". No final, vá do início ao fim e verifique se o mesmo valor de lixo ocorre e descarte.
fonte
ArrayList
, para armazenar o resultado da união.Integer
vez deint
. Então você pode usar emnull
vez do seu "valor de lixo". "Valores de lixo" ou "valores de sentinela" geralmente são uma má idéia, porque esses valores ainda podem ocorrer na entrada.Após o teste, aqui está minha melhor abordagem de interseção.
Velocidade mais rápida em comparação com a abordagem HashSet pura. O HashSet e o HashMap abaixo apresentam desempenho semelhante para matrizes com mais de 1 milhão de registros.
Quanto à abordagem do Java 8 Stream, a velocidade é bastante lenta para um tamanho de matriz maior que 10k.
Espero que isso possa ajudar.
fonte
Use o método retentAll () para encontrar o elemento comum ... ou seja, interseção list1.retainAll (list2)
fonte
Se você tivesse seus dados em Sets, poderia usar a
Sets
classe Guava .fonte
Se o número corresponder ao que eu estou verificando, ocorrerá pela primeira vez ou não com a ajuda de "indexOf ()" se o número corresponder à primeira vez, imprima e salve em uma string para que, na próxima vez que o mesmo número corresponda, ele será vencido ' t imprime porque devido à condição "indexOf ()" será falsa.
}
fonte