0Pricing
Java Academy · Lektion

Sortieren nach mehreren Schlüsseln mit thenComparing

Verketten Sie Comparatoren mit thenComparing, um nach mehreren Feldern in Prioritätsreihenfolge zu sortieren.

Sortieren nach mehreren Schlüsseln mit thenComparing ist eine kostenlose Java Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Java Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.

Sortierung nach mehreren Schlüsseln

thenComparing() verkettet Comparatoren, um nach mehreren Feldern zu sortieren. Zuerst wird das primäre Feld sortiert, bei Gleichheit das sekundäre und so weiter.

Grundlagen von thenComparing

Verwenden Sie thenComparing(), um Gleichstände nach dem primären Comparator aufzulösen.

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);

Sortierung auf drei Ebenen

Verketten Sie beliebig viele thenComparing-Ebenen.

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 mit Comparator

Verwenden Sie die Überladung, die einen Comparator akzeptiert, wenn Sie für sekundäre Schlüssel eine umgekehrte oder benutzerdefinierte Ordnung benötigen.

Comparator<Employee> sort = Comparator
    .comparing(Employee::dept)
    .thenComparing(Comparator.comparing(Employee::salary).reversed()); // highest paid first
    // equivalent: .thenComparingDouble(Employee::salary, Comparator.reverseOrder())

Sortierung mit null-Feldern

Kombinieren Sie thenComparing mit nullsLast/nullsFirst, um optionale Felder zuverlässig zu behandeln.

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);

Dynamische Auswahl des Sortierschlüssels

Wählen Sie den Sortierschlüssel zur Laufzeit anhand der Präferenz der Benutzerin oder des Benutzers aus.

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 mit einer Extraktorfunktion

Die Überladung thenComparing(Function<T,U>) extrahiert einen Comparable-Schlüssel für die sekundäre Sortierung, ohne dass ein expliziter Comparator erforderlich ist.

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);

Collections von Records sortieren

Records mit Zugriffsmethoden funktionieren nahtlos mit Methodenreferenzen in Comparator-Verkettungen.

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 einer stabilen Sortierung

Die List.sort()- und Arrays.sort()-Methoden von Java verwenden für Objekte eine stabile Mergesort-Implementierung. Elemente, die als gleich verglichen werden, behalten ihre ursprüngliche relative Reihenfolge bei.

// 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 sorted

Comparator.comparing mit Schlüssel-Comparator

Mit der zweistelligen Form Comparator.comparing(keyExtractor, keyComparator) können Sie sowohl den Schlüssel als auch dessen Ordnung festlegen.

// 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]

Praxisbeispiel: Flugsuchergebnisse

Flugsuchergebnisse nach Preis, anschließend nach Dauer und dann nach Abflugzeit sortieren.

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);

Sortierte Ergebnisse sammeln

Kombinieren Sie die Sortierung nach mehreren Schlüsseln mit Collectors, um sortierte Gruppen oder Maps zu erstellen.

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()));
});

Kurztest

Sie möchten Mitarbeitende zuerst alphabetisch nach Abteilung und anschließend absteigend nach Gehalt sortieren. Welche Kette ist korrekt?

Zusammenfassung: Sortierung nach mehreren Schlüsseln mit thenComparing

Die wichtigsten Erkenntnisse:

  • thenComparing() fügt sekundäre Sortierschlüssel hinzu, die angewendet werden, wenn die primären Schlüssel gleich sind
  • Verketten Sie so viele thenComparing-Stufen wie nötig
  • Verwenden Sie thenComparing(Comparator) mit reversed(), wenn der sekundäre Schlüssel absteigend sortiert werden soll
  • Kombinieren Sie dies bei optionalen Feldern mit nullsFirst/nullsLast
  • Java's List.sort() ist stabil – gleiche Elemente behalten ihre ursprüngliche Reihenfolge bei
  • Dynamische Sortierauswahl: Verwenden Sie switch, um zur Laufzeit den richtigen Comparator zurückzugeben

Häufig gestellte Fragen

Ist die Lektion „Sortieren nach mehreren Schlüsseln mit thenComparing“ kostenlos?

Ja — der vollständige Text von „Sortieren nach mehreren Schlüsseln mit thenComparing“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Java Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Sortieren nach mehreren Schlüsseln mit thenComparing“?

Verketten Sie Comparatoren mit thenComparing, um nach mehreren Feldern in Prioritätsreihenfolge zu sortieren. Du übst Java Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Java Academy zu starten?

Keine Vorkenntnisse erforderlich. Java Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.

Wie lange dauert die Lektion „Sortieren nach mehreren Schlüsseln mit thenComparing“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Java Academy-Lektion Code schreiben und ausführen?

Ja. Jede Java Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Die Comparable-Schnittstelle
  2. Comparator und Sortieren mit Lambdas
  3. Sortieren nach mehreren Schlüsseln mit thenComparing
  4. Arrays und Collections in der Praxis sortieren
← Zurück zu Java Academy