Comparator-Schnittstelle
Teil des Abschnitts Objektorientierte Programmierung der Java-Journey von Coddy. Lektion 45 von 87.
Während Comparable die natürliche Sortierreihenfolge einer Klasse definiert, musst du Objekte manchmal auf unterschiedliche Weise sortieren. Mit dem Interface Comparator kannst du eine separate Vergleichslogik erstellen, ohne die ursprüngliche Klasse zu verändern.
Ein Comparator ist ein externes Objekt, das zwei Objekte desselben Typs vergleicht. Das ist nützlich, wenn du mehrere Sortieroptionen möchtest oder die Klasse selbst nicht ändern kannst:
import java.util.Comparator;
class NameComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return p1.getName().compareTo(p2.getName());
}
}
class AgeComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return p1.getAge() - p2.getAge();
}
}Du kannst den Komparator dann an Sortiermethoden übergeben:
List<Person> people = new ArrayList<>();
people.add(new Person("Charlie", 30));
people.add(new Person("Alice", 25));
Collections.sort(people, new NameComparator()); // Sortiert nach Name
Collections.sort(people, new AgeComparator()); // Sortiert nach AlterFür prägnanten Code kannst du Lambda-Ausdrücke verwenden, da Comparator ein funktionales Interface ist:
Collections.sort(people, (p1, p2) -> p1.getName().compareTo(p2.getName()));Der wesentliche Unterschied: Comparable wird von der zu vergleichenden Klasse implementiert und definiert eine natürliche Reihenfolge, während Comparator eine separate Klasse ist, die unbegrenzt viele benutzerdefinierte Reihenfolgen definieren kann.
Aufgabe
EinfachErstellen wir ein Sortiersystem für Mitarbeiter, das die Leistungsfähigkeit der Comparator-Schnittstelle demonstriert. Du wirst mehrere Comparatoren erstellen, um Mitarbeiter auf unterschiedliche Weise zu sortieren – nach Gehalt und nach Namen –, ohne die Employee-Klasse selbst zu ändern.
Du wirst deinen Code auf vier Dateien verteilen:
Employee.java: Erstelle eine Klasse, die einen Mitarbeiter mit drei privaten Feldern darstellt:name(String),department(String) undsalary(double). Füge einen Konstruktor hinzu, der alle Felder initialisiert, sowie Getter-Methoden für jedes Feld. ÜberschreibetoString(), sodass folgende Ausgabe zurückgegeben wird:[name] ([department]) - $[salary]SalaryComparator.java: Erstelle einen Comparator, der Mitarbeiter nach ihrem Gehalt in absteigender Reihenfolge sortiert (die bestbezahlten zuerst). Implementiere dieComparator<Employee>-Schnittstelle und ihrecompare()-Methode. VerwendeDouble.compare()für einen sicheren Vergleich der Gehaltswerte.NameComparator.java: Erstelle einen weiteren Comparator, der Mitarbeiter alphabetisch nach ihrem Namen in aufsteigender Reihenfolge sortiert (A bis Z). ImplementiereComparator<Employee>und verwende diecompareTo()-Methode von String für den Vergleich.Main.java: Führe alles zusammen, indem du eine Liste von Mitarbeitern erstellst und sie mithilfe deiner Comparatoren sortierst. Du erhältst Eingaben für drei Mitarbeiter, jeweils in einer separaten Zeile und im folgenden Format:name,department,salaryErstelle eine
ArrayListmit Mitarbeitern und demonstriere anschließend beide Sortieransätze:- Sortiere zuerst nach Gehalt mithilfe deines
SalaryComparatorund gib jeden Mitarbeiter aus - Gib eine leere Zeile aus
- Sortiere anschließend nach Namen mithilfe deines
NameComparatorund gib jeden Mitarbeiter aus
- Sortiere zuerst nach Gehalt mithilfe deines
Du erhältst drei Eingabezeilen, die jeweils Mitarbeiterdaten im folgenden Format enthalten: name,department,salary
Eine Eingabezeile könnte zum Beispiel so aussehen: Alice,Engineering,75000.0
Denke daran, java.util.Comparator in deine Comparator-Dateien sowie java.util.ArrayList, java.util.Collections und java.util.Scanner in deine Main-Datei zu importieren. Beachte, wie Comparatoren es dir ermöglichen, mehrere Sortierstrategien extern zu definieren: Die Employee-Klasse muss nichts darüber wissen, wie sie möglicherweise sortiert wird!
Probier es selbst
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Lies drei Mitarbeiter aus der Eingabe
// Jede Zeile im Format: name,department,salary
String line1 = scanner.nextLine();
String line2 = scanner.nextLine();
String line3 = scanner.nextLine();
// TODO: Parse jede Zeile und erstelle Employee-Objekte
// Hint: Verwende split(",") um die Werte zu trennen
// TODO: Erstelle eine ArrayList von Mitarbeitern und füge alle drei hinzu
// TODO: Sortiere nach Gehalt mit SalaryComparator und gib jeden Mitarbeiter aus
// Hint: Verwende Collections.sort(list, comparator)
// TODO: Gib eine leere Zeile aus
// TODO: Sortiere nach Name mit NameComparator und gib jeden Mitarbeiter aus
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in die OOPKlassen vs. ObjekteDas Schlüsselwort thisMethodenFelder (Attribute)KonstruktormethodeÜberladen von KonstruktorenRückblick – Einfacher Taschenrechner4Vererbung
Grundlegende Vererbung (extends)Das Schlüsselwort superÜberschreiben von Methoden (@Override)KonstruktorverkettungDie Object-KlasseEinfach- und mehrstufige VererbungWarum keine Mehrfachvererbung von KlassenRückblick – Mitarbeiterhierarchie7Spezielle Methoden & Object-Klasse
toString()-Methodeequals() und hashCode()clone()-MethodecompareTo() und ComparableComparator-SchnittstelleRückblick – Benutzerdefinierte Sortierung2Zugriffsmodifikatoren & Kapselung
Übersicht der ZugriffsebenenGetter- und Setter-MethodenInformationsverbergungDas Schlüsselwort finalRückblick – Bankkontoverwaltung5Polymorphismus
Grundlagen der MethodenüberladungMethodenüberschreibung (Laufzeit)Upcasting und DowncastingDer instanceof-OperatorAbstrakte Klassen und MethodenRückblick – Formrechner8Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungAggregation vs. KompositionInnere, verschachtelte & anonyme KlassenEnums und Enum-MethodenRecords (Java 16+)Versiegelte Klassen (Java 17+)11Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterBuilder-MusterObserver-MusterStrategie-Muster14Abschließende Herausforderungen
E-Learning-PlattformBankingsystemEntwicklung einer SpielfigurFahrzeugvermietungsdienst3Klassen-Props & statische Member
Instanz- vs. statische VariablenStatische MethodenStatische BlöckeKonstanten (static final)Wiederholung – Counter & Utility6Schnittstellen & abstrakte Klassen
Einführung in InterfacesInterfaces implementierenMehrere Interfaces implementierenDefault & Static in InterfacesAbstrakte Klassen vs. InterfacesFunktionale InterfacesRückblick – ZahlungssystemÜbe selbstständig: Online-Java-Compiler