W3docs

Como Remover Duplicatas de uma Lista em Java

Remova duplicatas de uma lista Java com HashSet, LinkedHashSet ou stream distinct.

Uma List em Java permite elementos duplicados por design, então quando você precisa que cada valor apareça apenas uma vez, é necessário remover as repetições manualmente. Este capítulo mostra as formas idiomáticas de fazer isso, com atenção a se a ordem de inserção original é preservada.

Usando um LinkedHashSet (ordem preservada)

A abordagem mais limpa é copiar a lista para um set, pois um Set rejeita duplicatas automaticamente. Use LinkedHashSet em vez de um simples HashSet para que a ordem de primeira ocorrência dos elementos seja mantida:

List<String> unique = new ArrayList<>(new LinkedHashSet<>(list));

Envolver o set novamente em um ArrayList devolve uma List, pronta para indexação ou trabalhos posteriores. O LinkedHashSet faz todo o trabalho pesado: ao ser preenchido a partir da lista original, ele descarta silenciosamente qualquer elemento que já tenha visto, enquanto sua estrutura encadeada lembra a ordem em que os elementos chegaram pela primeira vez.

Se você não se importa com a ordem, um HashSet simples é marginalmente mais rápido e usa um pouco menos de memória. Porém, ele embaralha a ordem dos elementos, o que raramente é o desejado ao exibir uma lista, então LinkedHashSet é o padrão seguro.

Usando a Stream API

A partir do Java 8, Stream.distinct() remove duplicatas em um pipeline único e legível. Assim como o LinkedHashSet, ele mantém a ordem de encontro dos elementos:

List<String> unique = list.stream()
        .distinct()
        .collect(Collectors.toList());

distinct() compara elementos com equals() e hashCode(), exatamente como um set faz, então seus objetos devem implementar esses métodos corretamente para tipos personalizados. Essa forma brilha quando a deduplicação é um passo em um pipeline maior — você pode encadear filter, map ou sorted ao redor dela sem introduzir uma coleção temporária.

Comparando as abordagens

Ambas as técnicas comuns dependem de equals/hashCode e ambas preservam a ordem de inserção; a diferença é principalmente de estilo e contexto.

AbordagemOrdem mantida?Melhor quando
LinkedHashSetSimUm one-liner rápido e sem dependências
HashSetNãoA ordem não importa e a velocidade é crítica
stream().distinct()SimA deduplicação faz parte de um pipeline de stream maior

Um ponto importante para todos eles: eles constroem uma nova coleção em vez de mutar a fonte. Se você precisar deduplicar no lugar, pode limpar a lista e re-adicionar os elementos únicos, ou atribuir o resultado de volta à mesma variável.

Exemplo prático

java— editable, runs on the server

O que observar na execução:

  • A lista original mantém todos os 7 elementos, incluindo os java e sql repetidos, pois uma List permite duplicatas.
  • O resultado do LinkedHashSet tem apenas 4 elementos — [java, sql, api, rest] — e eles aparecem na ordem de primeira ocorrência, sem ordenação ou embaralhamento.
  • O resultado de stream().distinct() é idêntico em tamanho e ordem, confirmando que as duas técnicas são intercambiáveis aqui.
  • deduped.equals(viaStream) imprime true, pois duas listas são iguais quando contêm os mesmos elementos na mesma ordem.
  • A lista original tags permanece inalterada, então as operações de deduplicação produziram novas listas em vez de mutar a fonte.

Prática

Prática
Qual tipo de coleção remove duplicatas preservando a ordem de inserção original dos elementos?
Qual tipo de coleção remove duplicatas preservando a ordem de inserção original dos elementos?
Was this page helpful?