Tri multicritère avec thenComparing
Enchaînez des comparateurs avec thenComparing pour trier selon plusieurs champs dans un ordre de priorité donné.
Tri multicritère avec thenComparing est une leçon Java Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Java Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Java Academy comprend 4 leçons au total.
Tri selon plusieurs clés
thenComparing() enchaîne les comparateurs pour trier selon plusieurs champs. Le tri principal est effectué en premier ; en cas d'égalité, le tri secondaire s'applique, et ainsi de suite.
thenComparing de base
Utilisez thenComparing() pour départager les égalités après le comparateur principal.
import java.util.*;
record Student(String name, int grade, double gpa) {}
List<Student> students = List.of(
new Student("Alice", 10, 3.9),
new Student("Bob", 11, 3.7),
new Student("Charlie", 10, 3.8),
new Student("Diana", 11, 3.7)
);
Comparator<Student> sort = Comparator.comparingInt(Student::grade)
.thenComparingDouble(Student::gpa).reversed()
.thenComparing(Student::name);
students.stream().sorted(sort).forEach(System.out::println);Tri à trois niveaux
Enchaînez autant de niveaux thenComparing que nécessaire.
record Employee(String dept, String team, String name, double salary) {}
List<Employee> employees = List.of(
new Employee("Eng", "Backend", "Alice", 95000),
new Employee("Eng", "Backend", "Bob", 92000),
new Employee("Eng", "Frontend","Charlie", 88000),
new Employee("Mkt", "Growth", "Diana", 75000)
);
Comparator<Employee> sort = Comparator
.comparing(Employee::dept)
.thenComparing(Employee::team)
.thenComparing(Comparator.comparingDouble(Employee::salary).reversed());
employees.stream().sorted(sort)
.forEach(e -> System.out.printf("%s > %s > %s: $%.0f%n",
e.dept(), e.team(), e.name(), e.salary()));thenComparing avec Comparator
Utilisez la surcharge qui accepte un Comparator lorsque vous avez besoin d'un ordre inversé ou personnalisé pour les clés secondaires.
Comparator<Employee> sort = Comparator
.comparing(Employee::dept)
.thenComparing(Comparator.comparing(Employee::salary).reversed()); // highest paid first
// equivalent: .thenComparingDouble(Employee::salary, Comparator.reverseOrder())Trier avec des champs null
Combinez thenComparing avec nullsLast/nullsFirst pour gérer correctement les champs facultatifs.
record Product(String name, String category, Double rating) {}
Comparator<Product> sort = Comparator
.comparing(Product::category, Comparator.nullsLast(Comparator.naturalOrder()))
.thenComparing(Product::rating, Comparator.nullsLast(Comparator.reverseOrder()))
.thenComparing(Product::name);Sélection dynamique de la clé de tri
Sélectionnez la clé de tri à l'exécution en fonction de la préférence de l'utilisateur.
static Comparator<Product> sortBy(String key) {
return switch (key) {
case "price" -> Comparator.comparingDouble(Product::price);
case "name" -> Comparator.comparing(Product::name);
case "stock" -> Comparator.comparingInt(Product::stock).reversed();
default -> Comparator.comparingDouble(Product::price);
};
}
String userChoice = "stock";
products.stream().sorted(sortBy(userChoice)).forEach(System.out::println);thenComparing avec une fonction d'extraction
La surcharge thenComparing(Function<T,U>) extrait une clé Comparable pour le tri secondaire sans nécessiter de Comparator explicite.
record Event(String type, int year, int month, int day) {}
Comparator<Event> chronological = Comparator
.comparing(Event::type)
.thenComparingInt(Event::year)
.thenComparingInt(Event::month)
.thenComparingInt(Event::day);Trier des collections d'enregistrements
Les enregistrements dotés de méthodes d'accès fonctionnent parfaitement avec les références de méthode dans les chaînes de comparateurs.
record Order(String customerId, String status, double total, java.time.LocalDate date) {}
List<Order> orders = loadOrders();
Comparator<Order> byCustomerThenDate = Comparator
.comparing(Order::customerId)
.thenComparing(Order::date, Comparator.reverseOrder()); // newest first per customer
orders.stream().sorted(byCustomerThenDate)
.collect(Collectors.groupingBy(Order::customerId))
.forEach((cust, ords) -> {
System.out.println("Customer: " + cust);
ords.forEach(o -> System.out.println(" " + o.date() + " $" + o.total()));
});Garantie de stabilité du tri
Les méthodes List.sort() et Arrays.sort() de Java pour les objets utilisent un tri stable par fusion. Les éléments considérés comme égaux conservent leur ordre relatif d'origine.
// Stable sort example:
// First sort by name, then by dept
// Equal dept elements preserve the name order from previous sort
List<Employee> sorted = employees.stream()
.sorted(Comparator.comparing(Employee::name)) // 1st pass
.sorted(Comparator.comparing(Employee::dept)) // 2nd pass (stable!)
.collect(Collectors.toList());
// Within each dept, employees remain alphabetically sortedComparator.comparing avec un comparateur de clés
La forme à deux arguments Comparator.comparing(keyExtractor, keyComparator) vous permet de spécifier à la fois la clé et son ordre.
// Sort by name length, then alphabetically within same length
Comparator<String> c = Comparator
.comparing(String::length, Integer::compare)
.thenComparing(Comparator.naturalOrder());
List<String> words = new ArrayList<>(List.of("fig","apple","kiwi","banana","pea"));
words.sort(c);
System.out.println(words); // [fig, pea, kiwi, apple, banana]Cas réel : résultats de recherche de vols
Tri des résultats de recherche de vols par prix, puis par durée et enfin par heure de départ.
record Flight(String airline, double price, int durationMin, java.time.LocalTime departs) {}
Comparator<Flight> bestFlight = Comparator
.comparingDouble(Flight::price)
.thenComparingInt(Flight::durationMin)
.thenComparing(Flight::departs);Collecte des résultats triés
Combinez le tri multicritère avec des collecteurs pour produire des groupes ou des tables associatives triés.
Map<String, List<Employee>> byDept = employees.stream()
.sorted(Comparator.comparing(Employee::dept)
.thenComparing(Comparator.comparingDouble(Employee::salary).reversed()))
.collect(Collectors.groupingBy(Employee::dept,
LinkedHashMap::new, // preserve insertion (sorted) order
Collectors.toList()));
byDept.forEach((dept, emps) -> {
System.out.println(dept + ":");
emps.forEach(e -> System.out.println(" " + e.name() + " $" + e.salary()));
});Vérification rapide
Vous souhaitez trier les employés d'abord par service dans l'ordre alphabétique, puis par salaire décroissant. Quelle chaîne est correcte ?
Récapitulatif : tri multicritère avec thenComparing
Points essentiels :
- thenComparing() ajoute des critères de tri secondaires, appliqués lorsque les critères principaux sont égaux
- Enchaînez autant de niveaux thenComparing que nécessaire
- Utilisez thenComparing(comparateur) avec reversed() lorsque le critère secondaire doit être en ordre décroissant
- Combinez avec nullsFirst/nullsLast pour les champs facultatifs
- List.sort() de Java est stable : les éléments égaux conservent leur ordre d'origine
- Sélection dynamique du tri : utilisez switch pour renvoyer le comparateur approprié à l'exécution
Questions Fréquemment Posées
La leçon « Tri multicritère avec thenComparing » est-elle gratuite ?
Oui — le texte complet de « Tri multicritère avec thenComparing » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Java Academy, passe à CoddyKit PRO. Le cours Java Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Tri multicritère avec thenComparing » ?
Enchaînez des comparateurs avec thenComparing pour trier selon plusieurs champs dans un ordre de priorité donné. Tu pratiques Java Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Java Academy ?
Aucune expérience préalable n'est requise. Java Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.
Combien de temps prend la leçon « Tri multicritère avec thenComparing » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Java Academy ?
Oui. Chaque leçon Java Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- L’interface Comparable
- Tri avec Comparator et des lambdas
- Tri multicritère avec thenComparing
- Trier des tableaux et des collections en pratique