ArrayList von benutzerdefinierten Objekten nach Eigenschaft sortieren

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);
    ...
}
Lösung

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 {
    @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() {
    @Override
    public int compare(MyObject o1, MyObject o2) {
        return o1.getStartDate().compareTo(o2.getStartDate());
    }
});

Seit [tag:java-8]

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.

Kommentare (12)

Ja, das können Sie. Es gibt zwei Optionen für den Vergleich von Elementen, die Schnittstelle Comparable und die Schnittstelle Comparator.

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.

Kommentare (0)

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

Kommentare (0)