Java-Sammlung sortieren

78

Ich habe eine Java-Sammlung:

Collection<CustomObject> list = new ArrayList<CustomObject>();

CustomObjecthat idjetzt ein Feld vor der Anzeigeliste Ich möchte diese Sammlung danach sortieren id.

Kann ich das auf irgendeine Weise tun?

Makky
quelle
Mögliches Duplikat von Wie sortiere ich eine Sammlung? <T>?
Hamdi

Antworten:

156

Verwenden Sie einen Komparator :

List<CustomObject> list = new ArrayList<CustomObject>();
Comparator<CustomObject> comparator = new Comparator<CustomObject>() {
    @Override
    public int compare(CustomObject left, CustomObject right) {
        return left.getId() - right.getId(); // use your logic
    }
};

Collections.sort(list, comparator); // use the comparator as much as u want
System.out.println(list);

Wenn es CustomObjectimplementiert ist Comparable, verwenden Sie es einfachCollections.sort(list)

Mit JDK 8 ist die Syntax viel einfacher.

List<CustomObject> list = getCustomObjectList();
Collections.sort(list, (left, right) -> left.getId() - right.getId());
System.out.println(list);

Viel einfacher

List<CustomObject> list = getCustomObjectList();
list.sort((left, right) -> left.getId() - right.getId());
System.out.println(list);

Am einfachsten

List<CustomObject> list = getCustomObjectList();
list.sort(Comparator.comparing(CustomObject::getId));
System.out.println(list);

Natürlich kann der ursprüngliche Code auch für JDK 8 verwendet werden.

Kowser
quelle
Was ist, wenn sie mehr als einmal sortieren möchten?
Hunter McMillen
Die Antwort wurde bearbeitet, bitte überprüfen. Offensichtlich ist es keine große Sache, wenn es verständlich ist, wie man den Komparator benutzt. Wenn Sie es einmal tun können, können Sie es auch n-mal tun :)
Kowser
Ja ... wenn die Klasse ein vergleichbares Gerät implementiert, muss der Komparator nicht bestanden werden ... nice ..ta
Makky
6
Die Methodensortierung (Liste <T>, Komparator <? Super T>) im Typ Sammlungen gilt nicht für die Argumente (Sammlung, Komparator), mit denen Sie eine Sammlung nicht an eine
Sortiermethode übergeben können, die absolut
5
Die Sortiermethode funktioniert für Listen, nicht für Sammlungen. Der Typ der Listenvariablen sollte in Liste geändert werden, damit dieses Beispiel funktioniert.
Eric Vasilik
34

Die Frage ist: "Sammlung sortieren". Sie können also nicht verwenden Collections.sort(List<T> l, Comparator<? super T> comparator).

Einige Hinweise:

Für Sammlungstyp:

Comparator<String> defaultComparator = new Comparator<String>() {
   @Override
   public int compare(String o1, String o2) {
       return o1.compareTo(o2);
   }
};

Collection<String> collection = getSomeStringCollection();
String[] strings = collection.toArray(new String[collection.size()]);
Arrays.sort(strings, defaultComparator);
List<String> sortedStrings = Arrays.asList(strings);

Collection<String> collection = getSomeStringCollection();
List<String> list = new ArrayList(collection);
Collections.sort(list, defaultComparator);
collection = list; // if you wish

Für Listentyp:

List<String> list = getSomeStringList();
Collections.sort(list, defaultComparator);

Für Set-Typ:

Set<String> set = getSomeStringSet();
// Than steps like in 'For Collection type' section or use java.util.TreeSet
// TreeSet sample:
// Sorted using java.lang.Comparable.
Set<String> naturalSorted = new TreeSet(set);

Set<String> set = getSomeStringSet();
Set<String> sortedSet = new TreeSet(defaultComparator);
sortedSet.addAll(set);

Java 8 Version. Es gibt eine java.util.List#sort(Comparator<? super E> c)Methode

List<String> list = getSomeStringList();
list.sort(defaultComparator);

oder

List<String> list = getSomeStringList();
list.sort((String o1, String o2) -> o1.compareTo(o2));

oder für Typen, die Comparable implementieren:

List<String> list = getSomeStringList();
list.sort(String::compareTo);
Aliaksei Yatsau
quelle
Ich habe diese Frage vor 4 Jahren gestellt und Sie antworten jetzt.
Makky
8
Danke für deine Antwort. Schätze es wirklich. 4 Jahre und immer noch falsche Antwort wird als richtig markiert. Wer ist der Böse?
Aliaksei Yatsau
2
@ Makky, weil es für eine Liste antwortet, nicht für eine Sammlung
NimChimpsky
11

Ein etwas anderes Beispiel besagt, dass Sie eine Klasse haben, die Comparable nicht implementiert, diese aber dennoch nach einem Feld oder einer Methode sortieren möchten.

Collections.sort(allMatching, new Comparator<ClassOne>() {
  @Override public int compare(final ClassOne o1, final ClassOne o2) {
    if (o1.getMethodToSort() > o2.getMethodToSort()) {
      return 1;
    } else if (o1.getMethodToSort() < o2.getMethodToSort()) {
      return -1;
    }  
    return 0;
  }
});
Shawn Vader
quelle
Die von Ihnen implementierte if-Anweisung macht genau das, was compareTo()bereits funktioniert.
Hunter McMillen
Der Unterschied besteht darin, dass in diesem Beispiel die Klasse ClassOne keine vergleichbare Klasse ist und Comparable nicht implementiert. Ich habe nur versucht, ein Beispiel zu zeigen, wie Sie eine Sammlung und einen Komparator verwenden können, um nicht vergleichbare Objekte zu sortieren. ClassOne hat keine compareTo-Methode.
Shawn Vader
funktioniert nicht mit Java 6 (Collections.sort beschränkt auf List)
Phil294
Sie werden in Java 7 oder 8 keine Collections.sort finden, die einen Satz nimmt. Per Definition ist eine Liste eine geordnete Folge von Elementen, während Satz eine eindeutige Liste von Elementen ist, die ungeordnet ist. Wenn Sie in einem Set bestellen möchten, schauen Sie sich TreeSet
Shawn Vader
7

Sie sollten die ComparatorSchnittstelle implementieren .

Beispiel:

public class CustomComparator implements Comparator<CustomObject> 
{
    @Override
    public int compare(CustomObject o1, CustomObject o2) {
        return o1.getId().compareTo(o2.getId());
    }
}

Dann können Sie die Collections-Klassenmethode Collections.sort()verwenden:

Collections.sort(list, new CustomComparator());
Hunter McMillen
quelle
5

Viele richtige Antworten, aber ich habe diese nicht gefunden: Sammlungen können nicht sortiert werden, Sie können sie nur durchlaufen.

Jetzt können Sie sie durchlaufen und eine neue Sortierung erstellen something. Folgen Sie dazu den Antworten hier.

estani
quelle
4

Ab Java 8 können Sie dies jetzt mit einem Stream mit einem Lambda tun:

list.stream().sorted(Comparator.comparing(customObject::getId))
             .foreach(object -> System.out.println(object));
GerSui
quelle
2

Verwenden Sie sort .

Sie müssen nur Folgendes tun:

Alle Elemente in der Liste müssen die Schnittstelle Comparable implementieren.

(Oder verwenden Sie die Version darunter, wie andere bereits gesagt haben.)

zw324
quelle
0

SortedSet und Komparator. Der Komparator sollte das ID- Feld berücksichtigen .

Aravind Yarram
quelle
@ Qwerky - Ich weiß, dass er eine Liste hat. Ich schlage ihm vor, ein Set zu verwenden. Es sei denn, er möchte Duplikate und Einfügereihenfolge beibehalten.
Aravind Yarram
0

Mit Java 8 haben Sie mehrere Möglichkeiten, Methodenreferenzen und den integrierten comparingKomparator zu kombinieren :

import static java.util.Comparator.comparing;

Collection<CustomObject> list = new ArrayList<CustomObject>();

Collections.sort(list, comparing(CustomObject::getId));
//or
list.sort(comparing(CustomObject::getId));
Assylien
quelle
0

Sie können die benutzerdefinierte Java-Klasse zum Sortieren verwenden.


quelle
-1

Sie können auch verwenden:

Collections.sort(list, new Comparator<CustomObject>() {
    public int compare(CustomObject obj1, CustomObject obj2) {
        return obj1.id - obj2.id;
    }
});
System.out.println(list);
Shrikant
quelle
-3

Um ganz klar zu sein, gibt Collection.sort (Liste, Kompartiment) nichts zurück, so dass so etwas list = Collection.sort(list, compartor);einen Fehler auslöst (void kann nicht in [ Listentyp ] konvertiert werden) und sollte es stattdessen seinCollection.sort(list, compartor)

user13979347
quelle
Völlig irrelevante Antwort.
Makky