Ich las über das Sortieren von ArrayLists mit einem Comparator, aber in allen Beispielen Leute verwendet compareTo
, die nach einigen Recherchen ist eine Methode für Strings.
Ich wollte eine ArrayList von benutzerdefinierten Objekten nach einer ihrer Eigenschaften sortieren: einem Datumsobjekt
(getStartDay()
). Normalerweise vergleiche ich sie nach item1.getStartDate().before(item2.getStartDate())
, also habe ich mich gefragt, ob ich etwas schreiben könnte wie:
public class CustomComparator {
public boolean compare(Object object1, Object object2) {
return object1.getStartDate().before(object2.getStartDate());
}
}
public class RandomName {
...
Collections.sort(Database.arrayList, new CustomComparator);
...
}
Da Date
Comparable
implementiert, verfügt es genau wie String
über eine Methode compareTo
.
Ihr benutzerdefinierter Comparator
könnte also wie folgt aussehen:
public class CustomComparator implements Comparator<MyObject> {
@Override
public int compare(MyObject o1, MyObject o2) {
return o1.getStartDate().compareTo(o2.getStartDate());
}
}
Die Methode Vergleichen()
muss einen Int
zurückgeben, Sie könnten also nicht direkt ein Bool
zurückgeben, wie Sie es sowieso vorhatten.
Ihr Sortiercode würde ungefähr so aussehen, wie Sie ihn geschrieben haben:
Collections.sort(Database.arrayList, new CustomComparator());
Ein etwas kürzerer Weg, dies alles zu schreiben, wenn Sie Ihren Komparator nicht wiederverwenden müssen, ist, ihn als anonyme Inline-Klasse zu schreiben:
Collections.sort(Database.arrayList, new Comparator<MyObject>() {
@Override
public int compare(MyObject o1, MyObject o2) {
return o1.getStartDate().compareTo(o2.getStartDate());
}
});
Sie können nun das letzte Beispiel in einer kürzeren Form schreiben, indem Sie einen Lambda-Ausdruck für den Comparator
verwenden:
Collections.sort(Database.arrayList,
(o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));
Und List
hat eine sort(Comparator)
-Methode, so dass Sie dies noch weiter verkürzen können:
Database.arrayList.sort((o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));
Dies ist ein so gängiges Idiom, dass es eine eingebaute Methode gibt, um einen Comparator
für eine Klasse mit einem Comparable
-Schlüssel zu erzeugen:
Database.arrayList.sort(Comparator.comparing(MyObject::getStartDate));
All dies sind äquivalente Formen.
Ja, das können Sie. Es gibt zwei Optionen für den Vergleich von Elementen, die Schnittstelle Comparable
Diese beiden Schnittstellen ermöglichen ein unterschiedliches Verhalten. Mit Comparable können Sie das Objekt so verhalten, wie Sie gerade Strings beschrieben haben (tatsächlich implementiert String Comparable). Die zweite Schnittstelle, Comparator, ermöglicht es Ihnen, das zu tun, worum Sie gebeten haben. Sie würden es so machen:
Collections.sort(myArrayList, new MyComparator());
Dadurch wird die Methode Collections.sort veranlasst, Ihren Komparator für den Sortiermechanismus zu verwenden. Wenn die Objekte in der ArrayList vergleichbar implementiert sind, können Sie stattdessen etwas wie folgt tun:
Collections.sort(myArrayList);
Die Klasse Collections enthält eine Reihe dieser nützlichen, allgemeinen Werkzeuge.
Ihre CustomComparator-Klasse muss java.util.Comparator implementieren, damit sie verwendet werden kann. Sie muss auch compare() UND equals() überschreiben.
compare() muss die Frage beantworten: Ist Objekt 1 kleiner als, gleich oder größer als Objekt 2?
Vollständige Unterlagen: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Comparator.html