Comparator und Comparable

JavaJavaBeginner
Jetzt üben

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

In Java-Anwendungen müssen wir oft Objekte vergleichen und sortieren. Bei primitiven Datentypen wie Ganzzahlen oder Zeichenketten weiß Java bereits, wie es diese vergleichen soll. Bei benutzerdefinierten Objekten müssen wir Java jedoch mitteilen, wie diese verglichen und geordnet werden sollen.

Java bietet zwei Schnittstellen (Interfaces), die bei diesem Vorgang helfen:

  • Das Comparable-Interface ermöglicht es einer Klasse, ihre natürliche Sortierreihenfolge zu definieren.
  • Das Comparator-Interface bietet externe Vergleichslogik, die für verschiedene Sortierkriterien verwendet werden kann.

In diesem Lab (LabEx) werden Sie lernen, wie Sie beide Schnittstellen implementieren und wie Sie sie nutzen, um Sammlungen von Objekten auf verschiedene Weise zu sortieren.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("Java")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["Object-Oriented and Advanced Concepts"]) java(("Java")) -.-> java/SystemandDataProcessingGroup(["System and Data Processing"]) java(("Java")) -.-> java/DataStructuresGroup(["Data Structures"]) java(("Java")) -.-> java/ProgrammingTechniquesGroup(["Programming Techniques"]) java/DataStructuresGroup -.-> java/sorting("Sorting") java/DataStructuresGroup -.-> java/collections_methods("Collections Methods") java/ProgrammingTechniquesGroup -.-> java/lambda("Lambda") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/classes_objects("Classes/Objects") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/class_methods("Class Methods") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/interface("Interface") java/SystemandDataProcessingGroup -.-> java/object_methods("Object Methods") subgraph Lab Skills java/sorting -.-> lab-117394{{"Comparator und Comparable"}} java/collections_methods -.-> lab-117394{{"Comparator und Comparable"}} java/lambda -.-> lab-117394{{"Comparator und Comparable"}} java/classes_objects -.-> lab-117394{{"Comparator und Comparable"}} java/class_methods -.-> lab-117394{{"Comparator und Comparable"}} java/interface -.-> lab-117394{{"Comparator und Comparable"}} java/object_methods -.-> lab-117394{{"Comparator und Comparable"}} end

Das Comparable-Interface verstehen

Das Comparable-Interface wird verwendet, wenn eine Klasse eine natürliche Sortierreihenfolge hat. Beispielsweise sind Zeichenketten (Strings) alphabetisch und Ganzzahlen numerisch sortiert.

Wenn eine Klasse das Comparable-Interface implementiert, muss sie eine compareTo()-Methode definieren, die angibt, wie Instanzen der Klasse geordnet werden sollen.

Erstellen einer einfachen Studentenklasse

Erstellen wir eine einfache Student-Klasse, um zu zeigen, wie man das Comparable-Interface verwendet. Wir definieren einen Studenten mit einem Namen, einer Durchschnittsnote (GPA) und einer Matrikelnummer.

  1. Öffnen Sie die WebIDE und erstellen Sie eine neue Datei namens Student.java im Verzeichnis ~/project mit folgendem Code:
public class Student implements Comparable<Student> {
    private String name;
    private double gpa;
    private int regNo;

    public Student(String name, double gpa, int regNo) {
        this.name = name;
        this.gpa = gpa;
        this.regNo = regNo;
    }

    // Implementing the compareTo method from Comparable interface
    @Override
    public int compareTo(Student other) {
        // Compare students based on GPA
        if (this.gpa < other.gpa) {
            return -1;
        } else if (this.gpa > other.gpa) {
            return 1;
        } else {
            return 0;
        }
    }

    // Getters
    public String getName() {
        return name;
    }

    public double getGpa() {
        return gpa;
    }

    public int getRegNo() {
        return regNo;
    }

    @Override
    public String toString() {
        return name + ", GPA: " + gpa + ", Reg No: " + regNo;
    }
}

Lassen Sie uns diesen Code verstehen:

  • Die Klasse Student implementiert das Comparable<Student>-Interface.
  • Die compareTo()-Methode vergleicht Studenten anhand ihrer Durchschnittsnote (GPA).
  • Wenn die Durchschnittsnote des aktuellen Studenten kleiner ist als die des anderen Studenten, geben wir -1 zurück.
  • Wenn die Durchschnittsnote des aktuellen Studenten größer ist als die des anderen Studenten, geben wir 1 zurück.
  • Wenn die Durchschnittsnoten gleich sind, geben wir 0 zurück.

Jetzt erstellen wir ein einfaches Testprogramm, um zu sehen, wie wir das Comparable-Interface verwenden können, um Studenten zu sortieren.

  1. Erstellen Sie eine neue Datei namens ComparableDemo.java im Verzeichnis ~/project mit folgendem Code:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ComparableDemo {
    public static void main(String[] args) {
        // Create a list of students
        List<Student> students = new ArrayList<>();
        students.add(new Student("John", 3.5, 101));
        students.add(new Student("Mary", 3.8, 102));
        students.add(new Student("Alice", 3.2, 103));
        students.add(new Student("Bob", 3.9, 104));

        // Print the unsorted list
        System.out.println("Unsorted Student List:");
        for (Student student : students) {
            System.out.println(student);
        }

        // Sort the list using the natural ordering (defined by compareTo method)
        Collections.sort(students);

        // Print the sorted list
        System.out.println("\nStudents sorted by GPA (using Comparable):");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

Dieses Programm:

  1. Erstellt eine Liste von Student-Objekten.

  2. Gibt die unsortierte Liste aus.

  3. Sortiert die Liste mit Collections.sort(), das die natürliche Sortierreihenfolge verwendet, die in der compareTo()-Methode definiert ist.

  4. Gibt die sortierte Liste aus.

  5. Jetzt kompilieren und führen wir unseren Code aus, um die Ausgabe zu sehen:

cd ~/project
javac Student.java ComparableDemo.java
java ComparableDemo

Sie sollten eine Ausgabe ähnlich wie diese sehen:

Unsorted Student List:
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102
Alice, GPA: 3.2, Reg No: 103
Bob, GPA: 3.9, Reg No: 104

Students sorted by GPA (using Comparable):
Alice, GPA: 3.2, Reg No: 103
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102
Bob, GPA: 3.9, Reg No: 104

Wie Sie sehen können, sind die Studenten jetzt nach ihrer Durchschnittsnote (GPA) in aufsteigender Reihenfolge sortiert. Dies ist die natürliche Sortierreihenfolge, die wir in der compareTo()-Methode definiert haben.

Erstellen und Verwenden von Comparatoren

Während das Comparable-Interface eine natürliche Sortierreihenfolge für eine Klasse definiert, müssen wir manchmal Objekte anhand unterschiedlicher Kriterien sortieren. Hier kommt das Comparator-Interface ins Spiel.

Das Comparator-Interface ermöglicht es uns, benutzerdefinierte Sortierlogik zu definieren, die unabhängig von der zu vergleichenden Klasse ist. Das bedeutet, dass wir mehrere Möglichkeiten haben, Objekte derselben Klasse zu sortieren.

Erstellen eines Comparators für die Sortierung nach Namen

Erstellen wir einen Comparator, der Studenten alphabetisch nach ihren Namen sortiert:

  1. Erstellen Sie eine neue Datei namens StudentNameComparator.java im Verzeichnis ~/project mit folgendem Code:
import java.util.Comparator;

public class StudentNameComparator implements Comparator<Student> {
    @Override
    public int compare(Student s1, Student s2) {
        // Compare students based on their names
        return s1.getName().compareTo(s2.getName());
    }
}

Dieser Comparator:

  • Implementiert das Comparator<Student>-Interface.
  • Definiert eine compare()-Methode, die zwei Student-Objekte entgegennimmt.
  • Vergleicht die Studenten anhand ihrer Namen mithilfe der compareTo()-Methode der String-Klasse.
  1. Jetzt erstellen wir ein Programm, um zu zeigen, wie man diesen Comparator verwendet. Erstellen Sie eine Datei namens ComparatorDemo.java im Verzeichnis ~/project:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ComparatorDemo {
    public static void main(String[] args) {
        // Create a list of students
        List<Student> students = new ArrayList<>();
        students.add(new Student("John", 3.5, 101));
        students.add(new Student("Mary", 3.8, 102));
        students.add(new Student("Alice", 3.2, 103));
        students.add(new Student("Bob", 3.9, 104));

        // Print the unsorted list
        System.out.println("Unsorted Student List:");
        for (Student student : students) {
            System.out.println(student);
        }

        // Sort by name using the StudentNameComparator
        Collections.sort(students, new StudentNameComparator());

        // Print the list sorted by name
        System.out.println("\nStudents sorted by name (using Comparator):");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

Dieses Programm:

  1. Erstellt eine Liste von Student-Objekten.

  2. Gibt die unsortierte Liste aus.

  3. Sortiert die Liste mit Collections.sort() unter Verwendung unseres benutzerdefinierten StudentNameComparator.

  4. Gibt die sortierte Liste aus.

  5. Kompilieren und führen wir unseren Code aus:

cd ~/project
javac Student.java StudentNameComparator.java ComparatorDemo.java
java ComparatorDemo

Sie sollten eine Ausgabe ähnlich wie diese sehen:

Unsorted Student List:
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102
Alice, GPA: 3.2, Reg No: 103
Bob, GPA: 3.9, Reg No: 104

Students sorted by name (using Comparator):
Alice, GPA: 3.2, Reg No: 103
Bob, GPA: 3.9, Reg No: 104
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102

Wie Sie sehen können, sind die Studenten jetzt alphabetisch nach Namen und nicht nach ihrer Durchschnittsnote (GPA) sortiert.

Verwenden von Lambda-Ausdrücken für Comparatoren

Mit Java 8 wurden Lambda-Ausdrücke eingeführt, die das Erstellen von Comparatoren vereinfachen können. Anstatt eine separate Klasse zu erstellen, können wir die Vergleichslogik direkt inline definieren.

  1. Erstellen Sie eine neue Datei namens LambdaComparatorDemo.java im Verzeichnis ~/project:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class LambdaComparatorDemo {
    public static void main(String[] args) {
        // Create a list of students
        List<Student> students = new ArrayList<>();
        students.add(new Student("John", 3.5, 101));
        students.add(new Student("Mary", 3.8, 102));
        students.add(new Student("Alice", 3.2, 103));
        students.add(new Student("Bob", 3.9, 104));

        // Sort by registration number using lambda expression
        Collections.sort(students, (s1, s2) -> s1.getRegNo() - s2.getRegNo());

        // Print the list sorted by registration number
        System.out.println("Students sorted by registration number (using lambda):");
        for (Student student : students) {
            System.out.println(student);
        }

        // Sort by name using method reference
        Collections.sort(students, Comparator.comparing(Student::getName));

        // Print the list sorted by name
        System.out.println("\nStudents sorted by name (using method reference):");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

Dieses Programm zeigt:

  1. Die Verwendung eines Lambda-Ausdrucks, um einen Comparator zu erstellen, der Studenten nach ihrer Matrikelnummer sortiert.

  2. Die Verwendung der Comparator.comparing()-Methode mit einer Methodenreferenz, um einen Comparator zu erstellen, der Studenten nach ihrem Namen sortiert.

  3. Kompilieren und führen Sie diesen Code aus:

cd ~/project
javac Student.java LambdaComparatorDemo.java
java LambdaComparatorDemo

Sie sollten eine Ausgabe ähnlich wie diese sehen:

Students sorted by registration number (using lambda):
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102
Alice, GPA: 3.2, Reg No: 103
Bob, GPA: 3.9, Reg No: 104

Students sorted by name (using method reference):
Alice, GPA: 3.2, Reg No: 103
Bob, GPA: 3.9, Reg No: 104
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102

Die Studenten werden zunächst nach ihrer Matrikelnummer und dann nach ihrem Namen sortiert.

Fortgeschrittene Sortiertechniken

In realen Anwendungen benötigen wir oft komplexere Sortierlogik, wie beispielsweise:

  • Sortieren nach mehreren Kriterien (z.B. zuerst nach Durchschnittsnote (GPA) sortieren, und wenn die GPAs gleich sind, nach Namen sortieren)
  • Sortieren in umgekehrter Reihenfolge
  • Erstellen von benutzerdefinierten Vergleichsketten (Comparator Chains)

Lassen Sie uns diese fortgeschrittenen Techniken untersuchen.

Sortieren nach mehreren Kriterien

  1. Erstellen Sie eine neue Datei namens MultiCriteriaDemo.java im Verzeichnis ~/project:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class MultiCriteriaDemo {
    public static void main(String[] args) {
        // Create a list of students with some having the same GPA
        List<Student> students = new ArrayList<>();
        students.add(new Student("John", 3.5, 101));
        students.add(new Student("Mary", 3.8, 102));
        students.add(new Student("Alice", 3.5, 103)); // Same GPA as John
        students.add(new Student("Bob", 3.8, 104));   // Same GPA as Mary
        students.add(new Student("Charlie", 3.2, 105));

        // Print the unsorted list
        System.out.println("Unsorted Student List:");
        for (Student student : students) {
            System.out.println(student);
        }

        // Sort first by GPA, then by name
        Comparator<Student> byGpa = Comparator.comparing(Student::getGpa);
        Comparator<Student> byName = Comparator.comparing(Student::getName);

        // Combine the comparators using thenComparing
        Comparator<Student> byGpaThenName = byGpa.thenComparing(byName);

        // Sort the list
        Collections.sort(students, byGpaThenName);

        // Print the sorted list
        System.out.println("\nStudents sorted by GPA, then by name:");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

Dieses Programm:

  1. Erstellt eine Liste von Studenten, wobei einige die gleiche Durchschnittsnote (GPA) haben.

  2. Erstellt einen Vergleicher (Comparator) für die GPA und einen für den Namen.

  3. Kombiniert diese Vergleicher mithilfe der thenComparing()-Methode.

  4. Sortiert die Studenten zuerst nach ihrer GPA und dann nach ihrem Namen, wenn die GPAs gleich sind.

  5. Kompilieren und führen Sie den Code aus:

cd ~/project
javac Student.java MultiCriteriaDemo.java
java MultiCriteriaDemo

Sie sollten eine Ausgabe ähnlich wie diese sehen:

Unsorted Student List:
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102
Alice, GPA: 3.5, Reg No: 103
Bob, GPA: 3.8, Reg No: 104
Charlie, GPA: 3.2, Reg No: 105

Students sorted by GPA, then by name:
Charlie, GPA: 3.2, Reg No: 105
Alice, GPA: 3.5, Reg No: 103
John, GPA: 3.5, Reg No: 101
Bob, GPA: 3.8, Reg No: 104
Mary, GPA: 3.8, Reg No: 102

Beachten Sie, dass Studenten mit der gleichen GPA (Alice und John mit 3.5, Bob und Mary mit 3.8) alphabetisch sortiert sind.

Sortieren in umgekehrter Reihenfolge

  1. Erstellen Sie eine neue Datei namens ReverseOrderDemo.java im Verzeichnis ~/project:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ReverseOrderDemo {
    public static void main(String[] args) {
        // Create a list of students
        List<Student> students = new ArrayList<>();
        students.add(new Student("John", 3.5, 101));
        students.add(new Student("Mary", 3.8, 102));
        students.add(new Student("Alice", 3.2, 103));
        students.add(new Student("Bob", 3.9, 104));
        students.add(new Student("Charlie", 3.0, 105));

        // Print the unsorted list
        System.out.println("Unsorted Student List:");
        for (Student student : students) {
            System.out.println(student);
        }

        // Method 1: Using Collections.reverseOrder() with a comparator
        Comparator<Student> byGpa = Comparator.comparing(Student::getGpa);
        Comparator<Student> byGpaReversed = Collections.reverseOrder(byGpa);

        Collections.sort(students, byGpaReversed);

        System.out.println("\nStudents sorted by GPA in descending order (Method 1):");
        for (Student student : students) {
            System.out.println(student);
        }

        // Method 2: Using the reversed() method of Comparator
        Collections.sort(students, Comparator.comparing(Student::getName).reversed());

        System.out.println("\nStudents sorted by name in reverse alphabetical order (Method 2):");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

Dieses Programm zeigt zwei Möglichkeiten, in umgekehrter Reihenfolge zu sortieren:

  1. Verwendung von Collections.reverseOrder() zum Umkehren eines Vergleichers.

  2. Verwendung der reversed()-Methode eines Vergleichers.

  3. Kompilieren und führen Sie den Code aus:

cd ~/project
javac Student.java ReverseOrderDemo.java
java ReverseOrderDemo

Sie sollten eine Ausgabe ähnlich wie diese sehen:

Unsorted Student List:
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102
Alice, GPA: 3.2, Reg No: 103
Bob, GPA: 3.9, Reg No: 104
Charlie, GPA: 3.0, Reg No: 105

Students sorted by GPA in descending order (Method 1):
Bob, GPA: 3.9, Reg No: 104
Mary, GPA: 3.8, Reg No: 102
John, GPA: 3.5, Reg No: 101
Alice, GPA: 3.2, Reg No: 103
Charlie, GPA: 3.0, Reg No: 105

Students sorted by name in reverse alphabetical order (Method 2):
Mary, GPA: 3.8, Reg No: 102
John, GPA: 3.5, Reg No: 101
Charlie, GPA: 3.0, Reg No: 105
Bob, GPA: 3.9, Reg No: 104
Alice, GPA: 3.2, Reg No: 103

Die erste Sortierung zeigt die Studenten in absteigender Reihenfolge nach ihrer GPA, und die zweite Sortierung zeigt die Studenten in umgekehrter alphabetischer Reihenfolge nach ihrem Namen.

Komplexe Sortierkette

  1. Erstellen wir ein weiteres Beispiel, das mehrere Kriterien und umgekehrte Sortierung kombiniert. Erstellen Sie eine Datei namens ComplexSortingDemo.java im Verzeichnis ~/project:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ComplexSortingDemo {
    public static void main(String[] args) {
        // Create a list of students with varied data
        List<Student> students = new ArrayList<>();
        students.add(new Student("John", 3.5, 101));
        students.add(new Student("Mary", 3.8, 102));
        students.add(new Student("Alice", 3.5, 103)); // Same GPA as John
        students.add(new Student("Bob", 3.8, 104));   // Same GPA as Mary
        students.add(new Student("Charlie", 3.2, 105));
        students.add(new Student("David", 3.2, 106)); // Same GPA as Charlie

        // Print the unsorted list
        System.out.println("Unsorted Student List:");
        for (Student student : students) {
            System.out.println(student);
        }

        // Create a complex sorting chain:
        // 1. Sort by GPA in descending order
        // 2. If GPAs are equal, sort by name in ascending order
        // 3. If names are also equal, sort by registration number in descending order
        Comparator<Student> complexComparator = Comparator
            .comparing(Student::getGpa, Comparator.reverseOrder())
            .thenComparing(Student::getName)
            .thenComparing(Student::getRegNo, Comparator.reverseOrder());

        Collections.sort(students, complexComparator);

        System.out.println("\nStudents sorted by complex criteria:");
        System.out.println("(GPA descending, then name ascending, then reg. number descending)");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

Dieses Programm erstellt eine komplexe Sortierkette, die:

  1. Zuerst die Studenten in absteigender Reihenfolge nach ihrer GPA sortiert.

  2. Wenn die GPAs gleich sind, in aufsteigender Reihenfolge nach ihrem Namen sortiert.

  3. Wenn sowohl die GPA als auch der Name gleich sind, in absteigender Reihenfolge nach ihrer Matrikelnummer sortiert.

  4. Kompilieren und führen Sie den Code aus:

cd ~/project
javac Student.java ComplexSortingDemo.java
java ComplexSortingDemo

Sie sollten eine Ausgabe ähnlich wie diese sehen:

Unsorted Student List:
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102
Alice, GPA: 3.5, Reg No: 103
Bob, GPA: 3.8, Reg No: 104
Charlie, GPA: 3.2, Reg No: 105
David, GPA: 3.2, Reg No: 106

Students sorted by complex criteria:
(GPA descending, then name ascending, then reg. number descending)
Bob, GPA: 3.8, Reg No: 104
Mary, GPA: 3.8, Reg No: 102
Alice, GPA: 3.5, Reg No: 103
John, GPA: 3.5, Reg No: 101
Charlie, GPA: 3.2, Reg No: 105
David, GPA: 3.2, Reg No: 106

In dieser Ausgabe:

  • Bob und Mary haben beide eine GPA von 3.8, aber Bob kommt alphabetisch zuerst.
  • Alice und John haben beide eine GPA von 3.5, aber Alice kommt alphabetisch zuerst.
  • Charlie und David haben beide eine GPA von 3.2, und Charlie kommt alphabetisch zuerst.

Dies zeigt, wie Sie komplexe, mehrstufige Sortierlogik durch Verkettung von Vergleichern erstellen können.

Erstellen einer vollständigen Sortieranwendung

Nachdem wir uns mit dem Comparable-Interface, dem Comparator-Interface und verschiedenen Sortiertechniken vertraut gemacht haben, setzen wir alles in einer vollständigen Anwendung um.

Wir werden ein Studentenverwaltungssystem erstellen, das es ermöglicht, Studenten auf verschiedene Arten zu sortieren.

  1. Zunächst erstellen wir eine aktualisierte Version unserer Student-Klasse. Diese Version implementiert Comparable und enthält eine verbesserte toString()-Methode für eine bessere Darstellung. Erstellen Sie eine Datei namens StudentManager.java im Verzeichnis ~/project:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;

class Student implements Comparable<Student> {
    private String name;
    private double gpa;
    private int regNo;
    private String major;

    public Student(String name, double gpa, int regNo, String major) {
        this.name = name;
        this.gpa = gpa;
        this.regNo = regNo;
        this.major = major;
    }

    @Override
    public int compareTo(Student other) {
        // Default natural ordering by registration number
        return this.regNo - other.regNo;
    }

    // Getters
    public String getName() {
        return name;
    }

    public double getGpa() {
        return gpa;
    }

    public int getRegNo() {
        return regNo;
    }

    public String getMajor() {
        return major;
    }

    @Override
    public String toString() {
        return String.format("%-10s | GPA: %.1f | Reg No: %-5d | Major: %-10s",
                            name, gpa, regNo, major);
    }
}

public class StudentManager {
    private List<Student> students;

    public StudentManager() {
        students = new ArrayList<>();
        // Add some sample students
        students.add(new Student("John", 3.5, 101, "Computer Science"));
        students.add(new Student("Mary", 3.8, 102, "Physics"));
        students.add(new Student("Alice", 3.5, 103, "Mathematics"));
        students.add(new Student("Bob", 3.9, 104, "Computer Science"));
        students.add(new Student("Charlie", 3.2, 105, "Physics"));
        students.add(new Student("David", 3.6, 106, "Mathematics"));
        students.add(new Student("Eve", 3.8, 107, "Biology"));
    }

    public void displayStudents() {
        System.out.println("----------------------------------------------------------");
        System.out.println("Name       | GPA   | Reg No | Major      ");
        System.out.println("----------------------------------------------------------");
        for (Student student : students) {
            System.out.println(student);
        }
        System.out.println("----------------------------------------------------------");
    }

    public void sortByNaturalOrder() {
        Collections.sort(students);
        System.out.println("\nStudents sorted by registration number (natural order):");
        displayStudents();
    }

    public void sortByName() {
        Collections.sort(students, Comparator.comparing(Student::getName));
        System.out.println("\nStudents sorted by name:");
        displayStudents();
    }

    public void sortByGpaDescending() {
        Collections.sort(students, Comparator.comparing(Student::getGpa).reversed());
        System.out.println("\nStudents sorted by GPA (descending):");
        displayStudents();
    }

    public void sortByMajorThenGpa() {
        Collections.sort(students,
            Comparator.comparing(Student::getMajor)
                     .thenComparing(Student::getGpa, Comparator.reverseOrder()));
        System.out.println("\nStudents sorted by major, then by GPA (descending):");
        displayStudents();
    }

    public static void main(String[] args) {
        StudentManager manager = new StudentManager();
        Scanner scanner = new Scanner(System.in);

        while (true) {
            System.out.println("\nStudent Manager");
            System.out.println("1. Display students (unsorted)");
            System.out.println("2. Sort by registration number");
            System.out.println("3. Sort by name");
            System.out.println("4. Sort by GPA (highest first)");
            System.out.println("5. Sort by major, then by GPA (highest first)");
            System.out.println("6. Exit");
            System.out.print("Enter your choice: ");

            int choice = scanner.nextInt();

            switch (choice) {
                case 1:
                    System.out.println("\nUnsorted student list:");
                    manager.displayStudents();
                    break;
                case 2:
                    manager.sortByNaturalOrder();
                    break;
                case 3:
                    manager.sortByName();
                    break;
                case 4:
                    manager.sortByGpaDescending();
                    break;
                case 5:
                    manager.sortByMajorThenGpa();
                    break;
                case 6:
                    System.out.println("Exiting program. Goodbye!");
                    scanner.close();
                    return;
                default:
                    System.out.println("Invalid choice. Please try again.");
            }
        }
    }
}

Diese Anwendung:

  1. Definiert eine Student-Klasse mit Name, Durchschnittsnote (GPA), Matrikelnummer und Studienfach.

  2. Implementiert Comparable, um die natürliche Sortierreihenfolge nach der Matrikelnummer zu definieren.

  3. Erstellt eine StudentManager-Klasse, die eine Liste von Studenten verwaltet.

  4. Bietet Methoden, um Studenten auf verschiedene Arten zu sortieren.

  5. Enthält eine einfache menügesteuerte Schnittstelle, damit der Benutzer verschiedene Sortieroptionen auswählen kann.

  6. Kompilieren und starten Sie die Anwendung:

cd ~/project
javac StudentManager.java
java StudentManager
  1. Testen Sie die Anwendung, indem Sie verschiedene Sortieroptionen ausprobieren. Hier ist ein Beispielinteraktionsablauf:
Student Manager
1. Display students (unsorted)
2. Sort by registration number
3. Sort by name
4. Sort by GPA (highest first)
5. Sort by major, then by GPA (highest first)
6. Exit
Enter your choice: 1

Unsorted student list:
----------------------------------------------------------
Name       | GPA   | Reg No | Major
----------------------------------------------------------
John       | GPA: 3.5 | Reg No: 101   | Major: Computer Science
Mary       | GPA: 3.8 | Reg No: 102   | Major: Physics
Alice      | GPA: 3.5 | Reg No: 103   | Major: Mathematics
Bob        | GPA: 3.9 | Reg No: 104   | Major: Computer Science
Charlie    | GPA: 3.2 | Reg No: 105   | Major: Physics
David      | GPA: 3.6 | Reg No: 106   | Major: Mathematics
Eve        | GPA: 3.8 | Reg No: 107   | Major: Biology
----------------------------------------------------------

Student Manager
1. Display students (unsorted)
2. Sort by registration number
3. Sort by name
4. Sort by GPA (highest first)
5. Sort by major, then by GPA (highest first)
6. Exit
Enter your choice: 3

Students sorted by name:
----------------------------------------------------------
Name       | GPA   | Reg No | Major
----------------------------------------------------------
Alice      | GPA: 3.5 | Reg No: 103   | Major: Mathematics
Bob        | GPA: 3.9 | Reg No: 104   | Major: Computer Science
Charlie    | GPA: 3.2 | Reg No: 105   | Major: Physics
David      | GPA: 3.6 | Reg No: 106   | Major: Mathematics
Eve        | GPA: 3.8 | Reg No: 107   | Major: Biology
John       | GPA: 3.5 | Reg No: 101   | Major: Computer Science
Mary       | GPA: 3.8 | Reg No: 102   | Major: Physics
----------------------------------------------------------

Student Manager
1. Display students (unsorted)
2. Sort by registration number
3. Sort by name
4. Sort by GPA (highest first)
5. Sort by major, then by GPA (highest first)
6. Exit
Enter your choice: 5

Students sorted by major, then by GPA (descending):
----------------------------------------------------------
Name       | GPA   | Reg No | Major
----------------------------------------------------------
Eve        | GPA: 3.8 | Reg No: 107   | Major: Biology
Bob        | GPA: 3.9 | Reg No: 104   | Major: Computer Science
John       | GPA: 3.5 | Reg No: 101   | Major: Computer Science
David      | GPA: 3.6 | Reg No: 106   | Major: Mathematics
Alice      | GPA: 3.5 | Reg No: 103   | Major: Mathematics
Mary       | GPA: 3.8 | Reg No: 102   | Major: Physics
Charlie    | GPA: 3.2 | Reg No: 105   | Major: Physics
----------------------------------------------------------

Student Manager
1. Display students (unsorted)
2. Sort by registration number
3. Sort by name
4. Sort by GPA (highest first)
5. Sort by major, then by GPA (highest first)
6. Exit
Enter your choice: 6
Exiting program. Goodbye!

Sie können verschiedene Sortieroptionen ausprobieren, um zu sehen, wie die Liste der Studenten jedes Mal unterschiedlich angezeigt wird.

Diese vollständige Anwendung zeigt die Stärke und Flexibilität der Comparable- und Comparator-Interfaces in Java. Sie ermöglicht es Ihnen, Objekte auf verschiedene Arten zu sortieren, um den unterschiedlichen Anforderungen Ihrer Anwendung gerecht zu werden.

Zusammenfassung

In diesem Lab haben Sie gelernt, wie Sie Objekte in Java mithilfe der Comparable- und Comparator-Interfaces vergleichen und sortieren können.

Gedankliche Schwerpunkte:

  1. Comparable-Interface

    • Implementieren der compareTo()-Methode, um die natürliche Sortierreihenfolge einer Klasse zu definieren
    • Verwenden von Collections.sort() mit Objekten, die eine natürliche Sortierreihenfolge haben
  2. Comparator-Interface

    • Erstellen von benutzerdefinierten Vergleichern (Comparator) für verschiedene Sortierkriterien
    • Verwenden von Collections.sort() mit einem benutzerdefinierten Vergleicher
    • Verwenden von Lambda-Ausdrücken und Methodenreferenzen zur kompakten Erstellung von Vergleichern
  3. Fortgeschrittene Sortiertechniken

    • Sortieren nach mehreren Kriterien mithilfe von thenComparing()
    • Sortieren in umgekehrter Reihenfolge mithilfe von Collections.reverseOrder() oder reversed()
    • Erstellen von komplexen Sortierketten
  4. Praktische Anwendung

    • Erstellen eines vollständigen Studentenverwaltungssystems mit verschiedenen Sortieroptionen
    • Implementieren einer Benutzeroberfläche, um verschiedene Sortierfunktionen zu demonstrieren

Diese Sortierfunktionen sind für viele Java-Anwendungen von grundlegender Bedeutung, insbesondere für solche, die mit Datensammlungen umgehen. Egal, ob Sie Studenten in einem Studentenverwaltungssystem, Bestellungen in einer E-Commerce-Anwendung oder irgendeine andere Art von Daten sortieren, die Techniken, die Sie in diesem Lab gelernt haben, werden Ihnen helfen, effiziente und flexible Sortierlogik zu implementieren.