Eu tenho uma lista do tipo inteiro, por exemplo:
[1, 1, 2, 3, 3, 3]
Eu gostaria de um método para retornar todas as duplicatas, por exemplo:
[1, 3]
Qual é a melhor maneira de fazer isso?
java
collections
mais fresco
fonte
fonte
Respostas:
O método
add
deSet
retorna um booleano se um valor já existe (verdadeiro se não existir, falso se já existir, consulte a documentação do conjunto ).Portanto, apenas itere por meio de todos os valores:
fonte
for (Integer yourInt
, para evitar boxing e unboxing desnecessários, especialmente porque sua entrada já contémInteger
s.HashSet
você também ter que considerar o fator de carga, por exemplo, quando você especifica uma capacidade inicial de100
, porque você deseja adicionar esse número de elementos, ele é arredondado para a próxima potência de 2 (128
), o que implica que com o fator de carga padrão de0.75f
, o limite de redimensionamento será96
, portanto, haverá um redimensionamento antes de você adicionar100
elementos. Felizmente, o redimensionamento não é mais tão caro. Com JREs atualizados, o redimensionamento não é mais um novo hashing, os elementos são apenas distribuídos entre seus dois locais de resultado possíveis com base no bit relevante.Eu precisava de uma solução para isso também. Usei a solução de Leifg e a tornei genérica.
fonte
Peguei a solução de John Strickler e a refiz para usar a API de streams introduzida no JDK8:
fonte
distinct()
método embutido também tem estado. Não consigo pensar em uma operação distinta eficiente (O (n)) que não tenha estado.Aqui está uma solução usando Streams com Java 8
Você apenas verifica se a frequência deste objeto está mais de uma vez em sua lista. Em seguida, chame .distinct () para ter apenas elementos exclusivos em seu resultado
fonte
Collections::frequency
é O (n). Ele precisa percorrer toda a coleção para encontrar a frequência de um item. E estamos chamando isso uma vez para cada item da coleção, o que torna esses trechosO(n^2)
. Você notará a diferença em qualquer coleção de mais de um punhado de elementos. Eu nunca usaria isso em código real.solução de base java 8:
fonte
Obviamente, você pode fazer o que quiser com eles (ou seja, colocar em um Conjunto para obter uma lista exclusiva de valores duplicados) em vez de imprimir ... Isso também tem a vantagem de registrar a localização dos itens duplicados.
fonte
Usando Guava em Java 8
fonte
Isso também funciona:
fonte
Você pode usar algo assim:
fonte
int
tipo de variável aqui. Isso significa que para cada iteração, um Integer é desempacotado uma vez e um int é embalado quatro vezes!Lambas pode ser uma solução
fonte
Use um MultiMap para armazenar cada valor como um conjunto de chave / valor. Em seguida, itere pelas chaves e encontre aquelas com vários valores.
fonte
Se você usar Eclipse Collections , isso funcionará:
Atualização: a partir das Coleções do Eclipse 9.2, agora você pode usar
selectDuplicates
Você também pode usar coleções primitivas para fazer isso:
Nota: Eu sou um committer para Eclipse Collections.
fonte
fonte
Semelhante a algumas respostas aqui, mas se você quiser encontrar duplicatas com base em alguma propriedade:
fonte
crie um
Map<Integer,Integer>
, itere a lista, se um elemento estiver no mapa, aumente seu valor, caso contrário, adicione-o ao mapa com chave = 1itere o mapa e adicione às listas todos os elementos com chave> = 2
fonte
Versão compacta gerada da resposta principal, também adicionado cheque vazio e tamanho de conjunto pré-alocado:
fonte
tempSet
comlistSize
quando necessário. Esta é uma pequena otimização, mas eu gosto.Eu peguei a resposta de Sebastian e adicionei um extrator chave a ela -
fonte
Uma alternativa thread-safe é esta:
fonte
Tente isso para encontrar itens duplicados na lista:
fonte
Isso deve funcionar para classificados e não classificados.
fonte
Este é um problema onde as técnicas funcionais brilham. Por exemplo, a seguinte solução F # é mais clara e menos sujeita a bugs do que a melhor solução Java imperativa (e trabalho diariamente com Java e F #).
Claro, esta questão é sobre Java. Portanto, minha sugestão é adotar uma biblioteca que traga recursos funcionais para o Java. Por exemplo, isso poderia ser resolvido usando minha própria biblioteca da seguinte maneira (e há várias outras por aí que vale a pena conferir também):
fonte
fonte
fonte
Este seria um bom método para encontrar valores duplicados, sem usar Set.
E digamos que você deseja um método que retorna uma lista distinta, ou seja, se você passar uma lista onde os elementos estão ocorrendo mais de uma vez, você obterá uma lista com elementos distintos.
fonte
E a versão que usa o
commons-collections
CollectionUtils.getCardinalityMap
método:`` `
fonte
Que tal este código -
fonte
apenas no caso de aqueles que também desejam incluir duplicatas e não duplicatas. basicamente a resposta semelhante à resposta correta, mas em vez de retornar de se não parte, você retorna a outra parte
use este código (mude para o tipo que você precisa)
fonte
Método mais genérico como variante de https://stackoverflow.com/a/52296246
fonte
Se você souber o valor máximo (por exemplo, <10000), você pode sacrificar espaço para velocidade. Não consigo lembrar o nome exato desta técnica.
pseudo-código:
fonte
Apenas tente isto:
Exemplo se os valores da lista são: [1, 2, 3, 4, 5, 6, 4, 3, 7, 8] item duplicado [3, 4].
fonte