Hier ist ein Tutorial zum Bestellen von Objekten:
Obwohl ich einige Beispiele geben werde, würde ich empfehlen, es trotzdem zu lesen.
Es gibt verschiedene Möglichkeiten, eine zu sortieren ArrayList
. Wenn Sie eine natürliche (Standard-) Reihenfolge definieren möchten, müssen Sie die Contact
Implementierung zulassen Comparable
. Angenommen, Sie möchten standardmäßig nach sortieren name
, dann tun Sie dies (der Einfachheit halber wurden keine Nullprüfungen durchgeführt):
public class Contact implements Comparable<Contact> {
private String name;
private String phone;
private Address address;
public int compareTo(Contact other) {
return name.compareTo(other.name);
}
// Add/generate getters/setters and other boilerplate.
}
damit du es einfach machen kannst
List<Contact> contacts = new ArrayList<Contact>();
// Fill it.
Collections.sort(contacts);
Wenn Sie eine externe steuerbare Reihenfolge definieren möchten (die die natürliche Reihenfolge überschreibt), müssen Sie Folgendes erstellen Comparator
:
List<Contact> contacts = new ArrayList<Contact>();
// Fill it.
// Now sort by address instead of name (default).
Collections.sort(contacts, new Comparator<Contact>() {
public int compare(Contact one, Contact other) {
return one.getAddress().compareTo(other.getAddress());
}
});
Sie können das Comparator
s sogar in Contact
sich selbst definieren , damit Sie es wiederverwenden können, anstatt es jedes Mal neu zu erstellen:
public class Contact {
private String name;
private String phone;
private Address address;
// ...
public static Comparator<Contact> COMPARE_BY_PHONE = new Comparator<Contact>() {
public int compare(Contact one, Contact other) {
return one.phone.compareTo(other.phone);
}
};
public static Comparator<Contact> COMPARE_BY_ADDRESS = new Comparator<Contact>() {
public int compare(Contact one, Contact other) {
return one.address.compareTo(other.address);
}
};
}
die wie folgt verwendet werden kann:
List<Contact> contacts = new ArrayList<Contact>();
// Fill it.
// Sort by address.
Collections.sort(contacts, Contact.COMPARE_BY_ADDRESS);
// Sort later by phone.
Collections.sort(contacts, Contact.COMPARE_BY_PHONE);
Und um das Oberteil abzurunden , könnten Sie einen generischen Javabean-Komparator verwenden :
public class BeanComparator implements Comparator<Object> {
private String getter;
public BeanComparator(String field) {
this.getter = "get" + field.substring(0, 1).toUpperCase() + field.substring(1);
}
public int compare(Object o1, Object o2) {
try {
if (o1 != null && o2 != null) {
o1 = o1.getClass().getMethod(getter, new Class[0]).invoke(o1, new Object[0]);
o2 = o2.getClass().getMethod(getter, new Class[0]).invoke(o2, new Object[0]);
}
} catch (Exception e) {
// If this exception occurs, then it is usually a fault of the developer.
throw new RuntimeException("Cannot compare " + o1 + " with " + o2 + " on " + getter, e);
}
return (o1 == null) ? -1 : ((o2 == null) ? 1 : ((Comparable<Object>) o1).compareTo(o2));
}
}
die Sie wie folgt verwenden können:
// Sort on "phone" field of the Contact bean.
Collections.sort(contacts, new BeanComparator("phone"));
(Wie Sie im Code sehen, sind möglicherweise bereits Nullfelder abgedeckt, um NPEs beim Sortieren zu vermeiden.)
String.CASE_INSENSITIVE_ORDER
und Freunden bekommen, aber ich mag sie. Erleichtert das Lesen des resultierenden Codes.static
und vielleichtfinal
auch ... oder so ähnlich ...(o1 == null && o2 == null) ? 0 :
am Anfang dieser Rückleitung?)Zusätzlich zu dem, was bereits veröffentlicht wurde, sollten Sie wissen, dass wir seit Java 8 unseren Code verkürzen und wie folgt schreiben können:
oder da List jetzt
sort
Methode hatErläuterung:
Seit Java 8 können funktionale Schnittstellen (Schnittstellen mit nur einer abstrakten Methode - sie können mehr Standard- oder statische Methoden haben) einfach implementiert werden mit:
arguments -> body
source::method
.Da
Comparator<T>
es nur eine abstrakte Methode gibt, handeltint compare(T o1, T o2)
es sich um eine funktionale Schnittstelle.Also statt (Beispiel aus @ BalusC Antwort )
Wir können diesen Code reduzieren auf:
Wir können dieses (oder jedes) Lambda durch Überspringen vereinfachen
{return
...}
Also statt
wir können schreiben
Außerdem gibt es jetzt
Comparator
statische Methoden wiecomparing(FunctionToComparableValue)
oder, mitcomparing(FunctionToValue, ValueComparator)
denen wir auf einfache Weise Komparatoren erstellen können, die bestimmte Werte von Objekten vergleichen sollen.Mit anderen Worten, wir können den obigen Code als umschreiben
quelle
Auf dieser Seite finden Sie alles, was Sie über das Sortieren von Sammlungen wie ArrayList wissen müssen.
Grundsätzlich müssen Sie
Contact
Klasse dieComparable
Schnittstelle von implementierenpublic int compareTo(Contact anotherContact)
darin.Collections.sort(myContactList);
,myContactList
istArrayList<Contact>
(oder eine andere Sammlung vonContact
).Es gibt auch eine andere Möglichkeit, eine Comparator-Klasse zu erstellen, und Sie können dies auch auf der verlinkten Seite nachlesen.
Beispiel:
quelle
BalusC und bguiz haben bereits sehr vollständige Antworten zur Verwendung der in Java integrierten Komparatoren gegeben.
Ich möchte nur hinzufügen, dass Google-Sammlungen eine Bestellklasse haben , die "leistungsfähiger" ist als die Standardkomparatoren. Es könnte sich lohnen, einen Blick darauf zu werfen. Sie können coole Dinge tun, z. B. Ordnungen zusammensetzen, umkehren, je nach Ergebnis einer Funktion für Ihre Objekte ordnen ...
Hier ist ein Blog-Beitrag, in dem einige seiner Vorteile erwähnt werden.
quelle
Sie müssen Ihre Contact-Klassen Comparable implementieren lassen und dann die
compareTo(Contact)
Methode implementieren . Auf diese Weise kann Collections.sort sie für Sie sortieren. Auf der Seite, auf die ich verlinkt habe, gibt compareTo 'eine negative Ganzzahl, eine Null oder eine positive Ganzzahl zurück, da dieses Objekt kleiner, gleich oder größer als das angegebene Objekt ist.'Wenn Sie beispielsweise nach Namen (von A bis Z) sortieren möchten, sieht Ihre Klasse folgendermaßen aus:
quelle
Mit Lambdaj können Sie eine Sammlung Ihrer Kontakte (z. B. nach ihrem Namen) wie folgt sortieren
oder durch ihre Adresse:
und so weiter. Im Allgemeinen bietet es ein DSL, mit dem Sie auf vielfältige Weise auf Ihre Sammlungen zugreifen und diese bearbeiten können, z. B. indem Sie Ihre Kontakte unter bestimmten Bedingungen filtern oder gruppieren, einige ihrer Eigenschaftswerte aggregieren usw.
quelle
Die Collections.sort ist eine gute Sortierimplementierung. Wenn Sie The Comparable for Contact nicht implementiert haben, müssen Sie eine Comparator-Implementierung übergeben
Bemerkenswert:
Die Zusammenführungssortierung ist wahrscheinlich besser als die meisten Suchalgorithmen, die Sie ausführen können.
quelle
Ich habe es folgendermaßen gemacht. Nummer und Name sind zwei Arraylisten. Ich muss den Namen sortieren. Wenn sich die Reihenfolge der Namensarralisten ändert, ändert auch die Reihenfolge der Arraylisten.
quelle
Verwenden Sie diese Methode:
`
und Verwendung: Sie müssen
mySortedlist = sortList(myList);
keinen Komparator in Ihrer Klasse implementieren. Wenn Sie in umgekehrter Reihenfolge tauschen möchten1
und-1
quelle
Ok, ich weiß, dass dies vor langer Zeit beantwortet wurde ... aber hier sind einige neue Informationen:
Angenommen, die betreffende Kontaktklasse hat bereits eine definierte natürliche Reihenfolge, indem Comparable implementiert wird. Sie möchten diese Reihenfolge jedoch überschreiben, beispielsweise nach Namen. Hier ist die moderne Vorgehensweise:
Auf diese Weise wird zuerst nach Namen sortiert (in umgekehrter Reihenfolge), und dann wird bei Namenskollisionen auf die von der Contact-Klasse selbst implementierte 'natürliche' Reihenfolge zurückgegriffen.
quelle
Sie sollten die Funktion Arrays.sort verwenden. Die enthaltenen Klassen sollten Comparable implementieren.
quelle