HOWTO · Java

Trier un ensemble en Java

Dans ce tutoriel, nous allons trier un ensemble en Java

Sur cette page

Un HashSet ne garantit aucun ordre d’itération ; ses éléments ne doivent donc pas être considérés comme triés. Pour obtenir des valeurs triées, copiez l’ensemble dans une List, puis triez cette copie, stockez les valeurs dans un TreeSet ou triez un flux au moment de produire le résultat. Le tri ne nécessite pas d’accès par indice : l’opération s’effectue sur la collection ou ses éléments. Les codes de hachage servent aux recherches fondées sur le hachage et peuvent influencer l’ordre d’itération observé d’un HashSet selon les détails d’implémentation, mais Java ne garantit aucun ordre d’itération pour un HashSet.

Pourquoi un Set nécessite une conversion ou un stockage ordonné

L’interface Set définit l’unicité des éléments, pas un ordre particulier. En particulier, un HashSet peut être parcouru dans un ordre différent de celui d’insertion, et cet ordre peut changer lorsque l’ensemble est modifié. Ne vous fiez ni à l’ordre observé pendant le débogage ni à celui d’une exécution particulière.

Le tri nécessite une règle d’ordre. Pour les nombres et les chaînes de caractères, l’ordre naturel de Java convient souvent. Pour vos propres types, vous devez définir leur ordre naturel ou fournir un Comparator qui compare les champs utiles à votre tâche. Choisissez la forme adaptée à votre besoin : une liste triée convient aux opérations sur les listes ou par indice, un TreeSet conserve les propriétés d’un ensemble, et un flux trié s’intègre à un pipeline de traitement.

Trier un Set en le copiant dans une liste

Copiez les éléments dans un ArrayList, puis appelez Collections.sort sur la liste. L’ensemble d’origine reste intact, et la liste obtenue est parcourue selon l’ordre choisi. L’exemple utilise des entiers, qui ont un ordre naturel ; pour un autre type, utilisez un comparateur qui exprime l’ordre souhaité. Les exemples n’ont pas été exécutés au cours de cette étape de rédaction ; les explications décrivent un comportement conforme aux règles d’ordre de Java.

Exécutez cet exemple :

Le code et les libellés ou sorties affichés dans cette section restent en anglais.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Main {
    public static void main(String[] args) {
        Set<Integer> numbers = new HashSet<>(Arrays.asList(3, 6, 4));
        List<Integer> sorted = new ArrayList<>(numbers);
        Collections.sort(sorted);
        System.out.println(sorted);
    }
}

La liste copiée suit l’ordre croissant des entiers. Cette approche convient lorsque vous avez besoin des opérations propres aux listes ou souhaitez préserver le contenu et la représentation de l’ensemble source.

Garder les éléments triés avec TreeSet

TreeSet est une classe qui stocke des éléments uniques selon leur ordre naturel ou un comparateur fourni. La construire à partir d’un ensemble copie ses éléments et fait suivre à l’itération cet ordre. L’ensemble d’origine reste inchangé.

Le code et les libellés ou sorties affichés dans cette section restent en anglais.

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;

public class Main {
    public static void main(String[] args) {
        Set<Integer> numbers = new HashSet<>(Arrays.asList(3, 6, 4));
        TreeSet<Integer> sorted = new TreeSet<>(numbers);
        System.out.println(sorted);
    }
}

L’itération suit l’ordre numérique naturel. Vous pouvez aussi passer un Comparator au constructeur de TreeSet pour obtenir un autre ordre. Un TreeSet détermine les doublons selon son ordre : si le comparateur renvoie zéro, les éléments concernés sont considérés comme un seul élément de l’ensemble. Veillez à ce que cette comparaison corresponde à la règle d’unicité souhaitée, en particulier si l’ordre est incompatible avec equals.

Trier les éléments d’un Set dans un flux

Appelez stream(), puis sorted() pour transmettre les éléments au reste du pipeline dans l’ordre. Cela ne réordonne ni ne modifie l’ensemble source : l’opération crée un flux trié pour la suite du traitement. Utilisez un comparateur avec sorted(comparator) si l’ordre naturel ne convient pas. Cette solution nécessite un environnement d’exécution qui prend en charge les flux.

Le code et les libellés ou sorties affichés dans cette section restent en anglais.

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class Main {
    public static void main(String[] args) {
        Set<Integer> numbers = new HashSet<>(Arrays.asList(20, 4, 15));
        numbers.stream().sorted().forEach(System.out::println);
    }
}

Le flux émet les valeurs par ordre croissant, tandis que numbers reste un ensemble sans garantie d’ordre d’itération. Cette approche est pratique lorsque les valeurs triées sont consommées immédiatement par des opérations comme forEach ; rassemblez-les dans une liste si le code suivant a besoin d’une liste triée réutilisable.

Choisir une approche et en comprendre les limites

Utilisez une copie triée lorsque l’opération suivante attend une List, lorsque vous avez besoin d’opérations propres aux listes ou lorsque vous souhaitez séparer l’ensemble d’origine de la copie. Utilisez un TreeSet si les itérations suivantes doivent rester ordonnées tout en conservant l’unicité d’un ensemble. Utilisez stream().sorted() lorsque le tri s’intègre à un pipeline et que vous devez seulement y traiter les éléments ordonnés.

Les trois approches nécessitent des éléments comparables : utilisez un ordre naturel adapté ou fournissez un comparateur. Un TreeSet impose une contrainte supplémentaire, car la comparaison détermine aussi quels éléments sont considérés comme des doublons ; un tri de liste ou de flux ne supprime pas les valeurs que le comparateur considère comme égales. Aucune de ces opérations ne transforme le HashSet d’origine en ensemble ordonné. Pour un affichage ponctuel, triez une copie ou traitez les valeurs dans un flux au lieu de modifier la collection utilisée ailleurs.