Ich habe eine Klasse Person
mit mehreren Eigenschaften, zum Beispiel:
public class Person {
private int id;
private String name, address;
// Many more properties.
}
Viele Person
-Objekte sind in einem gespeichert ArrayList<Person>
. Ich möchte diese Liste nach mehreren Sortierparametern sortieren, die sich von Zeit zu Zeit unterscheiden. Zum Beispiel möchte ich vielleicht einmal nach name
aufsteigend und dann address
absteigend sortieren und ein anderes Mal nur nach id
absteigend.
Und ich möchte keine eigenen Sortiermethoden erstellen (dh verwenden) Collections.sort(personList, someComparator)
. Was ist die eleganteste Lösung, mit der dies erreicht wird?
comparator.reversed()
zum Absteigen undcomparator1.thenComparing(comparator2)
zum Verketten von Komparatoren verwenden können.Sie können Komparatoren für jede Eigenschaft erstellen, die Sie sortieren möchten, und dann "Komparatorverkettung" versuchen :-) wie folgt:
quelle
Eine Möglichkeit besteht darin, eine
Comparator
Liste mit Eigenschaften zu erstellen , nach denen sortiert werden soll, wie in diesem Beispiel gezeigt.Es kann dann beispielsweise wie folgt im Code verwendet werden:
quelle
Ein Ansatz wäre,
Comparator
s zu komponieren . Dies könnte eine Bibliotheksmethode sein (ich bin sicher, dass sie irgendwo da draußen existiert).Verwenden:
Beachten Sie alternativ, dass dies
Collections.sort
eine stabile Sortierung ist. Wenn die Leistung nicht unbedingt entscheidend ist, sortieren Sie die sekundäre Reihenfolge vor der primären.quelle
compose(nameComparator, compose(addressComparator, idComparator))
Das würde etwas besser lesen, wenn Java Erweiterungsmethoden hätte.Mit Comparators können Sie dies sehr einfach und natürlich tun. Sie können einzelne Instanzen von Komparatoren erstellen, entweder in Ihrer Person-Klasse selbst oder in einer Service-Klasse, die Ihrem Bedarf zugeordnet ist.
Beispiele für anonyme innere Klassen:
Wenn Sie viele haben, können Sie Ihren Komparatorcode auch beliebig strukturieren. Zum Beispiel könnten Sie:
quelle
Ich denke, die Kopplung der Sortierer an die Person-Klasse, wie in Ihrer Antwort, ist keine gute Idee, da dadurch der Vergleich (normalerweise geschäftsorientiert) und das Modellobjekt nahe beieinander gekoppelt werden. Jedes Mal, wenn Sie den Sortierer ändern / hinzufügen möchten, müssen Sie die Personenklasse berühren, was normalerweise nicht der Fall ist.
Die Verwendung eines Dienstes oder eines ähnlichen Dienstes, der Komparatorinstanzen bereitstellt, wie von KLE vorgeschlagen, klingt viel flexibler und erweiterbarer.
quelle
Mein Ansatz basiert auf dem von Yishai. Die Hauptlücke besteht darin, dass es keine Möglichkeit gibt, zuerst aufsteigend nach einem Attribut und danach absteigend nach einem anderen zu sortieren. Dies ist mit Aufzählungen nicht möglich. Dafür habe ich Klassen benutzt. Da der SortOrder stark vom Typ abhängt, habe ich es vorgezogen, ihn als innere Personenklasse zu implementieren.
Die Klasse 'Person' mit der inneren Klasse 'SortOrder':
Ein Beispiel für die Verwendung der Klasse Person und ihrer SortOrder:
ORUMOO
quelle
Ich habe kürzlich einen Komparator geschrieben, um mehrere Felder innerhalb eines begrenzten String-Datensatzes zu sortieren. Hier können Sie das Trennzeichen, die Datensatzstruktur und die Sortierregeln definieren (von denen einige typspezifisch sind). Sie können dies verwenden, indem Sie einen Personendatensatz in einen durch Trennzeichen getrennten String konvertieren.
Erforderliche Informationen werden entweder programmgesteuert oder über eine XML-Datei in den Komparator selbst übertragen.
XML wird durch eine in ein Paket eingebettete XSD-Datei validiert. Im Folgenden finden Sie beispielsweise ein tabulatorgetrenntes Datensatzlayout mit vier Feldern (von denen zwei sortierbar sind):
Sie würden dies dann in Java wie folgt verwenden:
Bibliothek finden Sie hier:
http://sourceforge.net/projects/multicolumnrowcomparator/
quelle
Angenommen, eine Klasse
Coordinate
ist vorhanden und muss auf beide Arten nach X-Koordinate und Y-Koordinate sortiert werden. Dafür werden zwei verschiedene Komparatoren benötigt. Unten ist das Beispielquelle