Die Unterschiede zwischenComparable und Comparator – So nutzen Sie beide effektiv
In Java sind die Interfaces Comparable
und Comparator
äußerst nützlich, wenn es darum geht, Sammlungen von Objekten zu sortieren. Java stellt einige eingebaute Methoden zur Verfügung, um primitive Typen und Wrapper-Klassen zu sortieren. In diesem Beitrag lernen Sie zunächst, wie Sie Arrays und Listen mit primitiven Typen und Wrapper-Klassen sortieren, und anschließend, wie Sie mithilfe der Schnittstellen Comparable
und Comparator
auch benutzerdefinierte Klassen sortieren können.
Sortieren von primitiven Arrays und Listen
Zunächst ein Beispiel, wie Sie primitive Arrays oder Arrays von Wrapper-Klassen in Java sortieren können. Im Folgenden wird der Code gezeigt, um ein Array von Ganzzahlen und ein Array von Strings zu sortieren:
package com.journaldev.sort;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class JavaObjectSorting {
public static void main(String[] args) {
// Sortieren eines primitiven Arrays (int)
int[] intArr = {5, 9, 1, 10};
Arrays.sort(intArr);
System.out.println(Arrays.toString(intArr));
// Sortieren eines String-Arrays
String[] strArr = {"A", "C", "B", "Z", "E"};
Arrays.sort(strArr);
System.out.println(Arrays.toString(strArr));
// Sortieren einer Liste von Wrapper-Klassen (Strings)
List strList = new ArrayList<>();
strList.add("A");
strList.add("C");
strList.add("B");
strList.add("Z");
strList.add("E");
Collections.sort(strList);
for (String str : strList) {
System.out.print(" " + str);
}
}
}
Ausgabe:
[1, 5, 9, 10]
[A, B, C, E, Z]
A B C E Z
Sortieren von Objekten benutzerdefinierter Klassen
Das Sortieren von Arrays mit Objekten benutzerdefinierter Klassen erfordert mehr Aufwand. Java bietet dafür die Schnittstellen Comparable
und Comparator
. Hier sehen Sie ein Beispiel, wie Sie ein Array von Employee
-Objekten sortieren:
package com.journaldev.sort;
public class Employee {
private int id;
private String name;
private int age;
private long salary;
public int getId() {
return id;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public long getSalary() {
return salary;
}
public Employee(int id, String name, int age, int salary) {
this.id = id;
this.name = name;
this.age = age;
this.salary = salary;
}
@Override
public String toString() {
return "[id=" + this.id + ", name=" + this.name + ", age=" + this.age + ", salary=" + this.salary + "]";
}
}
Beim Versuch, dieses Array direkt zu sortieren, tritt eine Laufzeit-Exception auf, da Employee
nicht das Comparable
-Interface implementiert.
Lösung mit Comparable:
Um das Problem zu beheben, implementieren wir das Interface Comparable
und überschreiben die Methode compareTo
, um die Standard-Sortierung der Employee
-Objekte nach ihrer id
zu ermöglichen:
package com.journaldev.sort;
public class Employee implements Comparable {
private int id;
private String name;
private int age;
private long salary;
@Override
public int compareTo(Employee emp) {
return this.id - emp.id;
}
@Override
public String toString() {
return "[id=" + this.id + ", name=" + this.name + ", age=" + this.age + ", salary=" + this.salary + "]";
}
}
Nach dieser Änderung können Sie nun das Employee
-Array sortieren:
Employee[] empArr = new Employee[4];
empArr[0] = new Employee(10, "Mikey", 25, 10000);
empArr[1] = new Employee(20, "Arun", 29, 20000);
empArr[2] = new Employee(5, "Lisa", 35, 5000);
empArr[3] = new Employee(1, "Pankaj", 32, 50000);
Arrays.sort(empArr);
System.out.println("Standard-Sortierung:\n" + Arrays.toString(empArr));
Ausgabe:
[id=1, name=Pankaj, age=32, salary=50000], [id=5, name=Lisa, age=35, salary=5000], [id=10, name=Mikey, age=25, salary=10000], [id=20, name=Arun, age=29, salary=20000]
Sortieren nach unterschiedlichen Kriterien mit Comparator
Während das Interface Comparable
nur eine Standard-Sortierung ermöglicht, können Sie mit dem Interface Comparator
verschiedene Sortierkriterien implementieren. Hier sind einige Beispiele für benutzerdefinierte Comparator-Implementierungen, mit denen Sie Mitarbeiter nach Salary
, Age
oder Name
sortieren können:
import java.util.Comparator;
public class Employee {
public static Comparator SalaryComparator = new Comparator() {
@Override
public int compare(Employee e1, Employee e2) {
return (int) (e1.getSalary() - e2.getSalary());
}
};
public static Comparator AgeComparator = new Comparator() {
@Override
public int compare(Employee e1, Employee e2) {
return e1.getAge() - e2.getAge();
}
};
public static Comparator NameComparator = new Comparator() {
@Override
public int compare(Employee e1, Employee e2) {
return e1.getName().compareTo(e2.getName());
}
};
}
Diese Comparatoren können verwendet werden, um das Employee
-Array nach verschiedenen Kriterien zu sortieren:
Arrays.sort(empArr, Employee.SalaryComparator);
System.out.println("Nach Gehalt sortiert:\n" + Arrays.toString(empArr));
Arrays.sort(empArr, Employee.AgeComparator);
System.out.println("Nach Alter sortiert:\n" + Arrays.toString(empArr));
Arrays.sort(empArr, Employee.NameComparator);
System.out.println("Nach Name sortiert:\n" + Arrays.toString(empArr));
Fazit
In Java bieten die Interfaces Comparable
und Comparator
eine äußerst flexible Möglichkeit, benutzerdefinierte Objekte zu sortieren. Das Comparable
-Interface definiert dabei eine feste Standard-Sortierreihenfolge, die sich besonders dann eignet, wenn eine einheitliche, immer gleiche Sortierung gewünscht ist. Hingegen ermöglicht das Comparator
-Interface das Sortieren nach unterschiedlichen Kriterien, was vor allem dann praktisch ist, wenn eine flexible und situationsabhängige Sortierung erforderlich ist.
Durch die Verwendung von Comparator
können Sie beliebig viele Sortiermethoden definieren und je nach Anwendungsfall entscheiden, welches Kriterium – etwa Gehalt, Alter oder Name – im Vordergrund steht. Diese Flexibilität hilft dabei, den unterschiedlichen Anforderungen der Praxis gerecht zu werden.