W3docs

Comment supprimer les doublons d'une liste en Java

Supprimez les doublons d'une liste Java avec un HashSet, un LinkedHashSet ou un flux distinct.

Une List en Java autorise les éléments en double par conception ; lorsque vous avez besoin que chaque valeur n'apparaisse qu'une seule fois, vous devez supprimer les répétitions vous-même. Ce chapitre présente les méthodes idiomatiques pour y parvenir, en tenant compte de la préservation ou non de l'ordre d'insertion initial.

Utiliser un LinkedHashSet (ordre préservé)

L'approche la plus propre consiste à copier la liste dans un ensemble, car un Set rejette automatiquement les doublons. Utilisez LinkedHashSet plutôt qu'un simple HashSet afin de conserver l'ordre d'apparition des éléments :

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

Envelopper de nouveau l'ensemble dans un ArrayList vous donne une List utilisable pour l'indexation ou d'autres traitements. Le LinkedHashSet effectue tout le travail : au fur et à mesure qu'il est rempli à partir de la liste originale, il écarte silencieusement tout élément déjà rencontré, tandis que sa structure chaînée mémorise l'ordre dans lequel les éléments sont apparus pour la première fois.

Si l'ordre ne vous importe pas, un simple HashSet est légèrement plus rapide et utilise un peu moins de mémoire. Mais il mélange l'ordre des éléments, ce qui est rarement souhaitable lors de l'affichage d'une liste ; LinkedHashSet est donc la valeur par défaut sûre.

Utiliser l'API Stream

Depuis Java 8, Stream.distinct() supprime les doublons en un seul pipeline lisible. Comme LinkedHashSet, il conserve l'ordre de rencontre des éléments :

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

distinct() compare les éléments avec equals() et hashCode(), exactement comme le fait un ensemble ; vos objets doivent donc implémenter ces méthodes correctement pour les types personnalisés. Cette forme est particulièrement adaptée lorsque la déduplication n'est qu'une étape dans un pipeline plus large — vous pouvez enchaîner filter, map ou sorted autour d'elle sans introduire de collection temporaire.

Comparaison des approches

Les deux techniques courantes reposent sur equals/hashCode et toutes deux préservent l'ordre d'insertion ; la différence tient principalement au style et au contexte.

ApprocheOrdre conservé ?Idéal quand
LinkedHashSetOuiUn one-liner simple et sans dépendance
HashSetNonL'ordre n'a pas d'importance et la vitesse est critique
stream().distinct()OuiLa déduplication fait partie d'un pipeline de flux plus large

Un point essentiel pour toutes ces approches : elles construisent une nouvelle collection plutôt que de modifier la source. Si vous devez dédupliquer en place, vous pouvez vider la liste et réajouter les éléments uniques, ou réassigner le résultat à la même variable.

Exemple concret

java— editable, runs on the server

Ce qu'il faut retenir de l'exécution :

  • La liste originale conserve ses 7 éléments, y compris les java et sql répétés, car une List autorise les doublons.
  • Le résultat du LinkedHashSet ne contient que 4 éléments — [java, sql, api, rest] — et ils apparaissent dans l'ordre de première rencontre, ni triés ni mélangés.
  • Le résultat de stream().distinct() est identique en taille et en ordre, confirmant que les deux techniques sont interchangeables ici.
  • deduped.equals(viaStream) affiche true, car deux listes sont égales lorsqu'elles contiennent les mêmes éléments dans le même ordre.
  • La liste tags originale est inchangée, donc les opérations de déduplication ont produit de nouvelles listes plutôt que de modifier la source.

Pratique

Pratique
Quel type de collection supprime les doublons tout en préservant l'ordre d'insertion initial des éléments ?
Quel type de collection supprime les doublons tout en préservant l'ordre d'insertion initial des éléments ?
Was this page helpful?