Java - Wie man Comparator verwendet?

Hallo zusammen, zukünftige Java-Zauberer! ? Heute begeben wir uns auf eine aufregende Reise in die Welt der Java Comparators. Keine Sorge, wenn du neu im Programmieren bist – ich werde dein freundlicher Guide sein, und wir gehen das Schritt für Schritt durch. Am Ende dieses Tutorials wirst du Objekte wie ein Profi sortieren können!

Java - Comparators

Was ist ein Comparator?

Bevor wir eintauchen, stellen wir uns vor, du organisiert dein Bücherregal. Du möchtest deine Bücher vielleicht nach Titel, Autor oder Erscheinungsdatum anordnen. In Java ist ein Comparator wie dein persönlicher Bibliothekar, der genau weiß, wie er deine Sammlung basierend auf den von dir gewählten Kriterien sortiert.

In technischen Begriffen ist ein Comparator eine Schnittstelle in Java, die es uns ermöglicht, eine benutzerdefinierte Ordnung für Objekte zu definieren. Er ist besonders nützlich, wenn wir Objekte sortieren möchten, die keine natürliche Ordnung haben, oder wenn wir sie in einer anderen als ihrer natürlichen Ordnung sortieren möchten.

Das Comparator Interface

Schauen wir uns das Comparator Interface genauer an:

public interface Comparator<T> {
int compare(T o1, T o2);
}

Lass dich nicht einschüchtern! Es ist einfacher, als es aussieht. Das <T> sagt nur, dass dieses Interface mit jedem Objekttyp arbeiten kann. Die compare-Methode ist der Ort, an dem die Magie passiert – es ist, als ob du deinen Bibliothekar fragst, zwei Bücher zu vergleichen.

Wie die compare Methode funktioniert

Die compare-Methode nimmt zwei Objekte und gibt eine Ganzzahl zurück:

  • Wenn das erste Objekt als "kleiner" als das zweite angesehen wird, gibt es eine negative Zahl zurück.
  • Wenn sie als "gleich" angesehen werden, gibt es null zurück.
  • Wenn das erste Objekt als "größer" angesehen wird, gibt es eine positive Zahl zurück.

Stelle es dir wie eine Waage vor. Wenn das erste Objekt leichter ist, neigt die Waage zur negativen Seite. Wenn sie gleich sind, bleibt sie bei null balanced. Wenn das erste schwerer ist, neigt sie zur positiven Seite.

Dein erster Comparator erstellen

Erstellen wir einen einfachen Comparator, um Strings nach ihrer Länge zu sortieren. Wir nennen ihn StringLengthComparator:

import java.util.Comparator;

public class StringLengthComparator implements Comparator<String> {
@Override
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}

Das ist, was passiert:

  1. Wir importieren das Comparator Interface aus java.util.
  2. Wir erstellen eine Klasse, die Comparator<String> implementiert, was bedeutet, dass sie String-Objekte vergleicht.
  3. Wir überschreiben die compare-Methode, um die Länge des zweiten Strings von der ersten abzuziehen.

Deinen Comparator verwenden

Nun, wo wir unseren Comparator haben, lassen ihn zu nutzen! Wir erstellen eine Liste von Strings und sortieren sie:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ComparatorExample {
public static void main(String[] args) {
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Pear");
fruits.add("Banana");
fruits.add("Kiwi");

System.out.println("Vor dem Sortieren: " + fruits);

Collections.sort(fruits, new StringLengthComparator());

System.out.println("Nach dem Sortieren: " + fruits);
}
}

Ausgabe:

Vor dem Sortieren: [Apple, Pear, Banana, Kiwi]
Nach dem Sortieren: [Pear, Kiwi, Apple, Banana]

Lassen wir das auseinanderfallen:

  1. Wir erstellen eine Liste von Obstnamen.
  2. Wir drucken die ursprüngliche Liste.
  3. Wir verwenden Collections.sort() mit unserem benutzerdefinierten Comparator, um die Liste zu sortieren.
  4. Wir drucken die sortierte Liste.

Beachte, wie die Früchte jetzt nach der Länge ihrer Namen sortiert sind!

Lambda-Ausdrücke: Ein Shortcut

Java 8 führte Lambda-Ausdrücke ein, die unseren Comparator noch kompakter machen können. Hier ist das gleiche Beispiel mit einer Lambda-Ausdrücken:

Collections.sort(fruits, (s1, s2) -> s1.length() - s2.length());

Dieser eine Ausdruck macht genau dasselbe wie unsere StringLengthComparator-Klasse! Es ist, als ob du Java sagst, "Wenn du zwei Strings vergleichst, ziehe einfach ihre Längen ab."

Sortieren von benutzerdefinierten Objekten

Nun, lassen uns das Level aufsteigen und einige benutzerdefinierte Objekte sortieren. Stellen wir uns eine Person-Klasse vor:

public class Person {
private String name;
private int age;

public Person(String name, int age) {
this.name = name;
this.age = age;
}

// Getter und Setter...

@Override
public String toString() {
return name + " (" + age + ")";
}
}

Wir können einen Comparator erstellen, um Person-Objekte nach Alter zu sortieren:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class PersonSortExample {
public static void main(String[] args) {
List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 25));
people.add(new Person("Bob", 30));
people.add(new Person("Charlie", 22));

System.out.println("Vor dem Sortieren: " + people);

Collections.sort(people, Comparator.comparingInt(Person::getAge));

System.out.println("Nach dem Sortieren: " + people);
}
}

Ausgabe:

Vor dem Sortieren: [Alice (25), Bob (30), Charlie (22)]
Nach dem Sortieren: [Charlie (22), Alice (25), Bob (30)]

Hier verwenden wir Comparator.comparingInt(), der einen Comparator basierend auf einem Ganzzahlwert erstellt – in diesem Fall das Alter. Die Person::getAge ist eine Methodenreferenz, die Java anweist, die getAge()-Methode zu verwenden, um den zu vergleichenden Wert zu erhalten.

Die Reihenfolge umkehren

Was ist, wenn wir in absteigender Reihenfolge sortieren möchten? Leicht wie Peasy! Verwende einfach die reversed()-Methode:

Collections.sort(people, Comparator.comparingInt(Person::getAge).reversed());

Dies wird unsere Person-Objekte von alt nach jung sortieren.

Chaining von Comparators

Manchmal möchten wir möglicherweise nach mehreren Kriterien sortieren. Zum Beispiel, lassen wir Person-Objekte nach Alter sortieren, und wenn die Alters gleich sind, nach Name:

Comparator<Person> ageAndNameComparator = Comparator
.comparingInt(Person::getAge)
.thenComparing(Person::getName);

Collections.sort(people, ageAndNameComparator);

Dies erstellt einen Comparator, der zuerst nach Alter vergleicht und wenn die Alters gleich sind, nach Namen vergleicht.

Schlussfolgerung

Herzlichen Glückwunsch! Du hast gerade die Ins und Outs der Java Comparators gelernt. Von der Sortierung einfacher Strings bis hin zu komplexen Objekten, du hast jetzt die Macht, Daten auf jede erdenkliche Weise zu organisieren. Denke daran, Übung macht den Meister, also habe keine Angst, mit verschiedenen Sortierkriterien und Objekten zu experimentieren.

Während du deine Java-Reise fortsetzt, wirst du Comparators als unentbehrliche Werkzeuge in deinem Programmierwerkzeugkasten finden. Sie sind nicht nur zum Sortieren von Listen da – sie werden in vielen Java-Sammlungen und Algorithmen verwendet, um Ordnung zu erhalten und effiziente Suchen durchzuführen.

Weiter codieren, weiter lernen und vor allem: Spaß haben! Wer weiß? Vielleicht schreibst du eines Tages einen Sortieralgorithmus, der die Art und Weise revolutioniert, wie wir Daten organisieren. Bis dahin, viel Spaß beim Vergleichen! ??‍??‍?

Methoden des Comparator Interface

Hier ist eine Tabelle der wichtigsten Methoden im Comparator Interface:

Methode Beschreibung
compare(T o1, T o2) Vergleicht seine beiden Argumente für die Ordnung.
equals(Object obj) Gibt an, ob ein anderes Objekt "gleich" diesem Comparator ist.
reversed() Gibt einen Comparator zurück, der die umgekehrte Ordnung dieses Comparators auferlegt.
thenComparing(Comparator<? super T> other) Gibt einen lexikographischen Comparator zurück, der mit einem anderen Comparator kombiniert ist.
thenComparingInt(ToIntFunction<? super T> keyExtractor) Gibt einen lexikographischen Comparator zurück, der mit einer Funktion kombiniert ist, die einen Ganzzahlwert extrahiert.
thenComparingLong(ToLongFunction<? super T> keyExtractor) Gibt einen lexikographischen Comparator zurück, der mit einer Funktion kombiniert ist, die einen Langwert extrahiert.
thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) Gibt einen lexikographischen Comparator zurück, der mit einer Funktion kombiniert ist, die einen Double-Wert extrahiert.

Diese Methoden bieten leistungsstarke Werkzeuge zur Erstellung komplexer Sortierlogik, die es dir ermöglichen,.Comparator für jeden Datentyp oder Sortieranforderung zu erstellen.

Credits: Image by storyset