Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lernen Comparator: Benutzerdefinierter Datenvergleich | Grundlagen und Funktionale Möglichkeiten der Stream-API
Stream-API

bookComparator: Benutzerdefinierter Datenvergleich

Betrachten wir die zweite funktionale Schnittstelle, Comparator, untersuchen, wie sie den Vergleich implementiert, und verstehen den Unterschied zwischen Comparator und Comparable.

Was ist Comparator?

Die Schlüsselmethode in der funktionalen Schnittstelle Comparator ist:

int compare(T o1, T o2);

Die Methode compare(T o1, T o2) gibt zurück:

  • Eine negative Zahl, wenn o1 kleiner als o2 ist;
  • Null, wenn o1 und o2 gleich sind;
  • Eine positive Zahl, wenn o1 größer als o2 ist.

Praktische Anwendung

Durchführung der Sortierung von Book-Objekten mithilfe des Comparator Interfaces. Anstatt die Vergleichsmethode direkt in der Klasse Book zu implementieren, werden statische Methoden aus dem Comparator interface zur Definition der Sortierlogik verwendet.

Main.java

Main.java

copy
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
package com.example; import java.util.List; import java.util.ArrayList; import java.util.Comparator; public class Main { public static void main(String[] args) { List<Book> books = new ArrayList<>(); books.add(new Book("The Great Gatsby", "F. Scott Fitzgerald", 1925)); books.add(new Book("To Kill a Mockingbird", "Harper Lee", 1960)); books.add(new Book("1984", "George Orwell", 1949)); // Sort by title books.sort(Comparator.comparing(Book::getTitle)); System.out.println("Sorted by title: " + books); System.out.println("------------------------"); // Sort by author books.sort(Comparator.comparing(Book::getAuthor)); System.out.println("Sorted by author: " + books); } } class Book { private String title; private String author; private int year; public Book(String title, String author, int year) { this.title = title; this.author = author; this.year = year; } public String getTitle() { return title; } public String getAuthor() { return author; } public int getYear() { return year; } @Override public String toString() { return title + " by " + author + " (" + year + ")"; } }

In diesem Beispiel wird das Comparator-Interface verwendet, um die Liste books zu sortieren. Aber warum wurde die Methode comparing() statt compare() verwendet?

Wenn die Methode compare() verwendet werden soll, muss ein Comparator-Objekt erstellt und die compare-Methode implementiert werden.

public static Comparator<Book> titleComparator = new Comparator<Book>() {
    @Override
    public int compare(Book b1, Book b2) {
        return b1.getTitle().compareTo(b2.getTitle());
    }
};

Dieser Code definiert einen Comparator<Book> mithilfe einer anonymen Klasse, um zwei Book-Objekte anhand ihres title zu vergleichen.

Da String das Interface Comparable implementiert, wird die Methode compareTo() verwendet, um die Titel lexikografisch zu vergleichen. Dabei wird ein negativer, null oder positiver Wert zurückgegeben.

Alternativ kann dasselbe Ergebnis mit einem Lambda-Ausdruck für eine kürzere Implementierung erzielt werden:

(b1, b2) -> b1.getTitle().compareTo(b2.getTitle());

Es gibt jedoch einen noch einfacheren Ansatz: die Verwendung der Methode Comparator.comparing(). Diese Methode übernimmt automatisch die Vergleichslogik und sorgt so für eine bessere Lesbarkeit und Kürze.

Es wird lediglich eine Methodenreferenz übergeben, die das Feld für den Vergleich extrahiert.

Comparator.comparing(Book::getTitle)

Die Methode sort() der Liste ruft den übergebenen Comparator auf, der wiederum die Reihenfolge der Elemente bestimmt, indem er sie anhand der von den angegebenen Methoden zurückgegebenen Werte vergleicht.

Mehrfaches Sortieren

Um nach mehreren Kriterien zu sortieren, kann die Methode thenComparing verwendet werden:

books.sort(
       Comparator.comparing(Book::getYear) // First by year
           .thenComparing(Book::getTitle) // Then by title
);

Dieses Beispiel zeigt, wie eine Liste von Büchern zunächst nach dem Veröffentlichungs-year und anschließend nach dem title sortiert wird. Der Sortiervorgang vergleicht die Bücher zuerst anhand ihres year. Haben zwei Bücher das gleiche year, erfolgt der Vergleich anhand des title, um die endgültige Reihenfolge festzulegen.

Umgekehrtes Sortieren

Das Umkehren der Sortierreihenfolge in Java ist nützlich, wenn Elemente zunächst nach einem Kriterium und anschließend in umgekehrter Reihenfolge nach einem weiteren Kriterium sortiert werden sollen.

Die Methoden reversed() und Comparator.reverseOrder() steuern die Sortierrichtung, funktionieren jedoch unterschiedlich.

books.sort(
    Comparator.comparing(Book::getYear).reversed() // Sort by year (descending)
        .thenComparing(Book::getTitle, Comparator.reverseOrder()) // Then by title (descending)
);

Die Bücher werden zunächst nach ihrem Erscheinungsjahr in absteigender Reihenfolge mit reversed() sortiert. Wenn mehrere Bücher das gleiche year haben, sortiert thenComparing() sie anhand des title in umgekehrter alphabetischer Reihenfolge mit Comparator.reverseOrder().

Dadurch erscheinen die neuesten Bücher zuerst, und innerhalb desselben Jahres werden die Titel von Z bis A angeordnet.

Unterschiede zwischen Comparable und Comparator

Die Comparable-Schnittstelle wird verwendet, wenn eine Klasse eine natürliche Ordnung besitzt, beispielsweise die Sortierung nach einem einzelnen Feld. Comparator wird verwendet, wenn nach mehreren Kriterien sortiert werden soll oder wenn eine benutzerdefinierte Reihenfolge für Objekte festgelegt werden muss.

1. Wann sollte das Comparable-Interface verwendet werden?

2. Wann sollte das Comparator-Interface verwendet werden?

question mark

Wann sollte das Comparable-Interface verwendet werden?

Select the correct answer

question mark

Wann sollte das Comparator-Interface verwendet werden?

Select the correct answer

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 1. Kapitel 9

Fragen Sie AI

expand

Fragen Sie AI

ChatGPT

Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen

Suggested prompts:

Can you explain the main differences between Comparator and Comparable?

How do I choose between using Comparator and Comparable in my code?

Can you show an example of sorting with Comparable?

Awesome!

Completion rate improved to 2.33

bookComparator: Benutzerdefinierter Datenvergleich

Swipe um das Menü anzuzeigen

Betrachten wir die zweite funktionale Schnittstelle, Comparator, untersuchen, wie sie den Vergleich implementiert, und verstehen den Unterschied zwischen Comparator und Comparable.

Was ist Comparator?

Die Schlüsselmethode in der funktionalen Schnittstelle Comparator ist:

int compare(T o1, T o2);

Die Methode compare(T o1, T o2) gibt zurück:

  • Eine negative Zahl, wenn o1 kleiner als o2 ist;
  • Null, wenn o1 und o2 gleich sind;
  • Eine positive Zahl, wenn o1 größer als o2 ist.

Praktische Anwendung

Durchführung der Sortierung von Book-Objekten mithilfe des Comparator Interfaces. Anstatt die Vergleichsmethode direkt in der Klasse Book zu implementieren, werden statische Methoden aus dem Comparator interface zur Definition der Sortierlogik verwendet.

Main.java

Main.java

copy
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
package com.example; import java.util.List; import java.util.ArrayList; import java.util.Comparator; public class Main { public static void main(String[] args) { List<Book> books = new ArrayList<>(); books.add(new Book("The Great Gatsby", "F. Scott Fitzgerald", 1925)); books.add(new Book("To Kill a Mockingbird", "Harper Lee", 1960)); books.add(new Book("1984", "George Orwell", 1949)); // Sort by title books.sort(Comparator.comparing(Book::getTitle)); System.out.println("Sorted by title: " + books); System.out.println("------------------------"); // Sort by author books.sort(Comparator.comparing(Book::getAuthor)); System.out.println("Sorted by author: " + books); } } class Book { private String title; private String author; private int year; public Book(String title, String author, int year) { this.title = title; this.author = author; this.year = year; } public String getTitle() { return title; } public String getAuthor() { return author; } public int getYear() { return year; } @Override public String toString() { return title + " by " + author + " (" + year + ")"; } }

In diesem Beispiel wird das Comparator-Interface verwendet, um die Liste books zu sortieren. Aber warum wurde die Methode comparing() statt compare() verwendet?

Wenn die Methode compare() verwendet werden soll, muss ein Comparator-Objekt erstellt und die compare-Methode implementiert werden.

public static Comparator<Book> titleComparator = new Comparator<Book>() {
    @Override
    public int compare(Book b1, Book b2) {
        return b1.getTitle().compareTo(b2.getTitle());
    }
};

Dieser Code definiert einen Comparator<Book> mithilfe einer anonymen Klasse, um zwei Book-Objekte anhand ihres title zu vergleichen.

Da String das Interface Comparable implementiert, wird die Methode compareTo() verwendet, um die Titel lexikografisch zu vergleichen. Dabei wird ein negativer, null oder positiver Wert zurückgegeben.

Alternativ kann dasselbe Ergebnis mit einem Lambda-Ausdruck für eine kürzere Implementierung erzielt werden:

(b1, b2) -> b1.getTitle().compareTo(b2.getTitle());

Es gibt jedoch einen noch einfacheren Ansatz: die Verwendung der Methode Comparator.comparing(). Diese Methode übernimmt automatisch die Vergleichslogik und sorgt so für eine bessere Lesbarkeit und Kürze.

Es wird lediglich eine Methodenreferenz übergeben, die das Feld für den Vergleich extrahiert.

Comparator.comparing(Book::getTitle)

Die Methode sort() der Liste ruft den übergebenen Comparator auf, der wiederum die Reihenfolge der Elemente bestimmt, indem er sie anhand der von den angegebenen Methoden zurückgegebenen Werte vergleicht.

Mehrfaches Sortieren

Um nach mehreren Kriterien zu sortieren, kann die Methode thenComparing verwendet werden:

books.sort(
       Comparator.comparing(Book::getYear) // First by year
           .thenComparing(Book::getTitle) // Then by title
);

Dieses Beispiel zeigt, wie eine Liste von Büchern zunächst nach dem Veröffentlichungs-year und anschließend nach dem title sortiert wird. Der Sortiervorgang vergleicht die Bücher zuerst anhand ihres year. Haben zwei Bücher das gleiche year, erfolgt der Vergleich anhand des title, um die endgültige Reihenfolge festzulegen.

Umgekehrtes Sortieren

Das Umkehren der Sortierreihenfolge in Java ist nützlich, wenn Elemente zunächst nach einem Kriterium und anschließend in umgekehrter Reihenfolge nach einem weiteren Kriterium sortiert werden sollen.

Die Methoden reversed() und Comparator.reverseOrder() steuern die Sortierrichtung, funktionieren jedoch unterschiedlich.

books.sort(
    Comparator.comparing(Book::getYear).reversed() // Sort by year (descending)
        .thenComparing(Book::getTitle, Comparator.reverseOrder()) // Then by title (descending)
);

Die Bücher werden zunächst nach ihrem Erscheinungsjahr in absteigender Reihenfolge mit reversed() sortiert. Wenn mehrere Bücher das gleiche year haben, sortiert thenComparing() sie anhand des title in umgekehrter alphabetischer Reihenfolge mit Comparator.reverseOrder().

Dadurch erscheinen die neuesten Bücher zuerst, und innerhalb desselben Jahres werden die Titel von Z bis A angeordnet.

Unterschiede zwischen Comparable und Comparator

Die Comparable-Schnittstelle wird verwendet, wenn eine Klasse eine natürliche Ordnung besitzt, beispielsweise die Sortierung nach einem einzelnen Feld. Comparator wird verwendet, wenn nach mehreren Kriterien sortiert werden soll oder wenn eine benutzerdefinierte Reihenfolge für Objekte festgelegt werden muss.

1. Wann sollte das Comparable-Interface verwendet werden?

2. Wann sollte das Comparator-Interface verwendet werden?

question mark

Wann sollte das Comparable-Interface verwendet werden?

Select the correct answer

question mark

Wann sollte das Comparator-Interface verwendet werden?

Select the correct answer

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 1. Kapitel 9
some-alt