Heim > Java > javaLernprogramm > Wie funktioniert Comparator in Java?

Wie funktioniert Comparator in Java?

Linda Hamilton
Freigeben: 2024-11-05 16:52:02
Original
660 Leute haben es durchsucht

¿Cómo funciona Comparator en Java?

Einführung

Manchmal entsteht bei der Arbeit an einem Projekt die Notwendigkeit, eine Art Sammlung von Objekten zu sortieren. Dafür denken Sie vielleicht, dass es notwendig ist, unsere eigenen Sortieralgorithmen zu implementieren, aber das ist etwas unnötig, obwohl es nicht schadet, es zu wissen wie sie funktionieren. Wenn Sie beispielsweise über ein Array von Ganzzahlen verfügen, können Sie die Methode Arrays.sort() verwenden, die ein Array von Grundelementen akzeptiert und es in aufsteigender Reihenfolge sortiert, wobei Sie sich die Tatsache zunutze machen, dass es nicht notwendig ist, das Ergebnis a zuzuweisen Neue Variable, da die Methode das ursprüngliche Array ändert.

int[] numbers = {9, 8, 5, 3, 1, 2, 4, 6, 7};
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers));

// Output
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Dies gilt auch, wenn Sie eine Sammlung benutzerdefinierter Objekte haben, zum Beispiel einen Datensatz vom Typ „Film“, aber wenn wir die Methode Arrays.sort() sehen, akzeptiert sie kein Array von Objekten dieses Typs, also muss sie es tun Verwenden Sie die Methode sort(), die als Parameter ein Objekt vom Typ T und ein Objekt vom Typ Comparator< akzeptiert. super T> Das ist eine funktionale Schnittstelle. Diese Schnittstelle ist sehr wichtig, da viele andere Methoden in Java sie verwenden, um Objekte auf benutzerdefinierte Weise zu vergleichen. Zum Beispiel die Collections.sort()-Methode oder die sort()-Methode eines List-Objekts, sogar Streams akzeptieren einen Komparator zum Sortieren der Elemente.

Was ist ein Komparator?

Die funktionale Schnittstelle Comparator (da sie funktional ist, kann sie als Lambda-Ausdruck geschrieben werden) ist eine Schnittstelle, die es Ihnen ermöglicht, zwei Objekte vom Typ T zu vergleichen, sodass sie zum Vergleichen von Ganzzahlen, Zeichenfolgen und benutzerdefinierten Werten verwendet wird Gegenstände usw Die Schnittstelle verfügt über mehrere statische und Standardmethoden, aber das Wichtigste ist die Methode „compare()“, die implementiert werden muss, um zwei Objekte zu vergleichen. vergleichen() empfängt zwei Objekte vom Typ T und gibt eine Ganzzahl zurück. Die Methodensignatur lautet wie folgt:

int compare(T o1, T o2);
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Diese Methode gibt eine negative Zahl zurück, wenn o1 kleiner als o2 ist, Null, wenn sie gleich sind, und eine positive Zahl, wenn o1 größer als o2 ist. Normalerweise gibt sie jeweils -1, 0 oder 1 zurück.

Was bedeutet es, dass ein Objekt kleiner, gleich oder größer als ein anderes ist?

Lassen Sie uns analysieren, was die Methode „compare()“ zurückgibt, da die Reihenfolge der Objekte davon abhängt. Es ist wichtig zu berücksichtigen, dass die Bedeutung dessen, was die Methode zurückgibt, relativ ist, d. h. ob Sie aufsteigend oder absteigend ordnen möchten. Es kommt auf die Situation und die Umsetzung an. Betrachten wir für jedes Beispiel den folgenden Datensatz:

int[] numbers = {9, 8, 5, 3, 1, 2, 4, 6, 7};
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers));

// Output
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
  • Wenn das erste Argument kleiner als das zweite ist, wird eine negative Zahl zurückgegeben. Um beispielsweise Filme nach Erscheinungsjahr zu sortieren, kann -1 zurückgegeben werden, wenn Film a kleiner als Film b ist:
int compare(T o1, T o2);
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
  • Wenn das erste Argument größer als das zweite ist, wird eine positive Zahl zurückgegeben. Um beispielsweise Filme nach Budget zu sortieren, kann 1 zurückgegeben werden, wenn Film a größer als Film b ist:
public record Movie(
        String name,
        List<String> actors,
        int budget,
        int year
) {
}
Nach dem Login kopieren
Nach dem Login kopieren
  • Wenn das erste Argument gleich dem zweiten ist, wird Null zurückgegeben. Um beispielsweise Filme nach der Anzahl der Schauspieler zu sortieren, kann 0 zurückgegeben werden, wenn Film a gleich Film b ist:
// a < b -> -1
a.year() < b.year() -> -1
Nach dem Login kopieren
Nach dem Login kopieren

Verwenden des Komparators

Angenommen, wir haben die folgenden Filme in einem Objekt vom Typ List:

// a > b -> 1
a.budget() > b.budget() -> 1
Nach dem Login kopieren
Nach dem Login kopieren

Wenn Sie die Filme nach Erscheinungsjahr in aufsteigender Reihenfolge ordnen möchten, können Sie ein Objekt vom Typ Comparator erstellen. und überschreiben Sie die Methode „compare()“ und übergeben Sie dieses Objekt dann an die Methode „sort()“ der Liste:

// a == b -> 0
a.actors().size() == b.actors().size() -> 0
Nach dem Login kopieren
Nach dem Login kopieren

Es kann auch als anonyme Klasse innerhalb der sort()-Methode implementiert werden:

Movie movie1 = new Movie("The Godfather", Arrays.asList("Marlon Brando", "Al Pacino"), 6000000, 1972);
Movie movie2 = new Movie("The Godfather: Part II", Arrays.asList("Al Pacino", "Robert De Niro"), 13000000, 1974);
Movie movie3 = new Movie("The Shawshank Redemption", Arrays.asList("Tim Robbins", "Morgan Freeman"), 25000000, 1994);
Movie movie4 = new Movie("The Dark Knight", Arrays.asList("Christian Bale", "Heath Ledger"), 185000000, 2008);

List<Movie> movies = Arrays.asList(movie1, movie2, movie3, movie4);
Nach dem Login kopieren
Nach dem Login kopieren

Oder prägnanter mit einem Lambda-Ausdruck direkt in der sort()-Methode:

Comparator<Movie> comparatorByYear = new Comparator<Movie>() {
    @Override
    public int compare(Movie o1, Movie o2) {
        return o1.year() - o2.year();
    }
};

movies.sort(comparatorByYear);
Nach dem Login kopieren
Nach dem Login kopieren

Bei jeder dieser Implementierungen wird die Liste aufsteigend nach Veröffentlichungsjahr sortiert. Wenn Sie in absteigender Reihenfolge sortieren möchten, können Sie die Reihenfolge der Argumente im Lambda-Ausdruck ändern oder bei der Subtraktion ein negatives Vorzeichen hinzufügen:

movies.sort(new Comparator<Movie>() {
    @Override
    public int compare(Movie o1, Movie o2) {
        return o1.year() - o2.year();
    }
});
Nach dem Login kopieren

Einige weitere Beispiele dafür, wie eine Liste benutzerdefinierter Objekte sortiert werden kann, sind:

  • Ordnen Sie die Filme nach der Anzahl der Schauspieler in aufsteigender Reihenfolge (weniger Schauspieler zu mehr Schauspielern):
movies.sort((p1, p2) -> p1.year() - p2.year());
Nach dem Login kopieren
  • Filme nach Budget in absteigender Reihenfolge sortieren (höchstes Budget zu niedrigstem Budget):
movies.sort((p1, p2) -> p2.year() - p1.year());
// o
movies.sort((p1, p2) -> - (p1.year() - p2.year()));
Nach dem Login kopieren
  • Filme nach Namen in aufsteigender Reihenfolge sortieren:
movies.sort((p1, p2) -> p1.actors().size() - p2.actors().size());
Nach dem Login kopieren

Unter anderem kann es vorkommen, dass eine Liste von Ganzzahlen in absteigender Reihenfolge sortiert werden muss

movies.sort((p1, p2) -> p2.budget() - p1.budget());
// o 
movies.sort((p1, p2) -> - (p1.budget() - p2.budget()));
Nach dem Login kopieren

Dazu können Sie auch die statische Methode Comparator.reverseOrder() verwenden, die einen Komparator zurückgibt, der die Elemente in absteigender Reihenfolge anordnet, und Comparator.naturalOrder(), der die Elemente in aufsteigender Reihenfolge anordnet.

int[] numbers = {9, 8, 5, 3, 1, 2, 4, 6, 7};
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers));

// Output
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Verwenden Sie Integer.compare()

In Java gibt es bereits Methoden, mit denen wir diese Art von Vergleichen auf effiziente Weise durchführen können, zum Beispiel Integer.compare(), das zwei ganze Zahlen vergleicht und eine negative Zahl zurückgibt, wenn das erste Argument kleiner als das zweite, Null, ist if sind gleich und eine positive Zahl, wenn das erste Argument größer als das zweite ist. Wenn wir analysieren, wie diese Methode funktioniert, können wir sehen, dass sie dem oben Erklärten ähnelt und genau das zurückgibt, was die Methode Compare() der Schnittstelle Comparator benötigt. Die Implementierung von Integer.compare() ist wie folgt:

int compare(T o1, T o2);
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Wenn Sie also die Filme nach Erscheinungsjahr in aufsteigender Reihenfolge sortieren möchten, können Sie Integer.compare():
verwenden

public record Movie(
        String name,
        List<String> actors,
        int budget,
        int year
) {
}
Nach dem Login kopieren
Nach dem Login kopieren

Verwendung von Referenzmethoden

Manchmal können Referenzmethoden verwendet werden, um Vergleiche anders als bisher durchzuführen, beispielsweise um eine Liste von Ganzzahlen in aufsteigender Reihenfolge zu sortieren:

// a < b -> -1
a.year() < b.year() -> -1
Nach dem Login kopieren
Nach dem Login kopieren

Integer ist nicht die einzige Klasse, die über eine Methode „compareTo()“ verfügt. String verfügt beispielsweise über eine Methode „compareTo()“, die zwei Zeichenfolgen lexikografisch vergleicht, sodass sie zum Sortieren einer Liste von Zeichenfolgen oder sogar zur Verwendung von CharSequence mit ihr verwendet werden kann Compare()-Methode (stellt technisch gesehen eine Folge von Zeichen dar).

// a > b -> 1
a.budget() > b.budget() -> 1
Nach dem Login kopieren
Nach dem Login kopieren

Um auf das Beispiel der Filme zurückzukommen: Wenn Sie die Filme nach Erscheinungsjahr in aufsteigender Reihenfolge sortieren möchten, können Sie die Methode „comparingInt()“ als Referenzmethode verwenden:

// a == b -> 0
a.actors().size() == b.actors().size() -> 0
Nach dem Login kopieren
Nach dem Login kopieren

Oder zum Vergleich anhand eines String-Typ-Attributs, in diesem Fall dem Namen des Films:

Movie movie1 = new Movie("The Godfather", Arrays.asList("Marlon Brando", "Al Pacino"), 6000000, 1972);
Movie movie2 = new Movie("The Godfather: Part II", Arrays.asList("Al Pacino", "Robert De Niro"), 13000000, 1974);
Movie movie3 = new Movie("The Shawshank Redemption", Arrays.asList("Tim Robbins", "Morgan Freeman"), 25000000, 1994);
Movie movie4 = new Movie("The Dark Knight", Arrays.asList("Christian Bale", "Heath Ledger"), 185000000, 2008);

List<Movie> movies = Arrays.asList(movie1, movie2, movie3, movie4);
Nach dem Login kopieren
Nach dem Login kopieren

Sortieren Sie nach mehreren Attributen

Manchmal müssen Sie möglicherweise eine Liste von Objekten nach mehreren Attributen sortieren. Wenn Sie beispielsweise Filme nach Erscheinungsjahr in aufsteigender Reihenfolge und nach Budget in absteigender Reihenfolge sortieren möchten, können Sie die Methode thenComparing() verwenden, die empfängt ein Komparator und ist für die Sortierung nach mehreren Attributen verantwortlich. Wenn es beispielsweise zwei Filme a und b mit demselben Erscheinungsjahr gibt, werden sie nach Budget sortiert.

Comparator<Movie> comparatorByYear = new Comparator<Movie>() {
    @Override
    public int compare(Movie o1, Movie o2) {
        return o1.year() - o2.year();
    }
};

movies.sort(comparatorByYear);
Nach dem Login kopieren
Nach dem Login kopieren

Schlussfolgerungen

Komparatoren sind in Java bei vielen Gelegenheiten nützlich, da sie es Ihnen ermöglichen, Objekte auf personalisierte Weise zu vergleichen, und nicht nur das, sondern sie können auch in vielen Java-Erfassungsmethoden verwendet werden und sogar mehr als einen Komparator zum Sortieren haben auf unterschiedliche Weise. In jedem Fall können Sie in der Comparator-Dokumentation innerhalb der IDE oder in der offiziellen Java-Dokumentation nachsehen, welche Methoden verwendet werden können und wie sie implementiert werden können.

Das obige ist der detaillierte Inhalt vonWie funktioniert Comparator in Java?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage