Wie sortiere ich einen Satz in einer Liste in Java?


169

In Java habe ich eine Set, und ich möchte daraus eine sortierte machen List. Gibt es eine Methode im java.util.CollectionsPaket, die dies für mich erledigt?

Antworten:


214

Die Antwort des OP ist nicht die beste. Es ist ineffizient, da es ein neues List und ein unnötiges neues Array erstellt. Außerdem werden "ungeprüfte" Warnungen aufgrund von Typensicherheitsproblemen bei generischen Arrays ausgegeben.

Verwenden Sie stattdessen Folgendes:

public static
<T extends Comparable<? super T>> List<T> asSortedList(Collection<T> c) {
  List<T> list = new ArrayList<T>(c);
  java.util.Collections.sort(list);
  return list;
}

Hier ist ein Anwendungsbeispiel:

Map<Integer, String> map = new HashMap<Integer, String>();
/* Add entries to the map. */
...
/* Now get a sorted list of the *values* in the map. */
Collection<String> unsorted = map.values();
List<String> sorted = Util.asSortedList(unsorted);

3
Vielen Dank! Diese SuppressWarnings haben mich immer gestört.
Jeremy Stein

4
@sunleo Die UtilKlasse enthält die asSortedList()Methode, die ich geschrieben habe. Mit anderen Worten, Sie schreiben die UtilKlasse selbst und fügen diesen Code ein.
Erickson

1
ha ha Ich dachte, es ist aus dem Standardpaket wie java.util ok danke.
Sunleo

3
Dies mag eine nette generische Utility-Funktion sein, aber Tatsache ist, dass sie immer noch nicht effizient ist. Ziehen Sie eine Sortierung vor Ort in Betracht, indem Sie sicherstellen, dass sich Ihr Set zunächst im richtigen Container befindet. Erwägen Sie auch die Verwendung des TreeSet als direkten Container Ihrer Daten. Wenn Ihre Daten ohnehin eindeutig sein müssen und Sie ein Set benötigen, verwenden Sie das TreeSet, um zwei Fliegen in einem Schlag zu fangen.
YoYo

1
Als Hinweis für die Leute, die nur die oberste Antwort lesen: Schauen Sie sich die Antwort von nschum unten an, in der die Streams von Java 8 verwendet werden. Wenn Sie Java 8 verwenden können, versuchen Sie es. Sie sind flexibler und effizienter.
Felk

74

Sortiertes Set:

return new TreeSet(setIWantSorted);

oder:

return new ArrayList(new TreeSet(setIWantSorted));

Dies war mein erster Gedanke, aber der Fragesteller wollte eine Liste
Alex B

@Alex: Dieser Ansatz kann weiterhin verwendet werden. Rückgabe einer neuen ArrayList (neues TreeSet (setIWantSorted))
Jonik

1
Ich habe diese Lösung tatsächlich verwendet, aber ich würde dies nicht empfehlen. Wie in der Dokumentation zu TreeSet angegeben (siehe download.oracle.com/javase/1.4.2/docs/api/java/util/… ), wird die Methode compareTo () anstelle der Methode equals () verwendet - wenn Sie dies tun Wenn zwei Objekte in der Gruppe das gleiche Ergebnis von equals () haben, werden sie als Duplikate angezeigt und als solche nicht zum TreeSet hinzugefügt. In acht nehmen.
Fwielstra

24
@fwielstra: Wie können Sie Objekte haben, die in der Eingabe gleich sind, da die Eingabe auch a ist Set?
Ryanprayogo

2
@ryanprayogo Es ist erwähnenswert, da s new TreeSetakzeptiert Collection, nicht nur Sets. Nicht jeder, der diese Antwort liest, wird ein verwenden Set, obwohl dies die ursprüngliche Frage ist.
Chris

44
List myList = new ArrayList(collection);
Collections.sort(myList);

… Sollte jedoch den Trick machen. Fügen Sie gegebenenfalls mit Generika Geschmack hinzu.


Ich hatte einen nützlichen Ausschnitt, den ich der Community spenden wollte. Als ich nach den Informationen suchte, konnte ich sie nicht finden. Ich habe versucht, die Arbeit der nächsten Person zu erleichtern. stackoverflow.com/questions/18557/…
Jeremy Stein

1
Ja, sicher, aber dieser Link, den Sie bereitgestellt haben, handelt tatsächlich von echten Fragen (dh von denen, auf die die Antwort nicht vorliegt, und finden Sie sie dann). Ihre Frage hier war nur, um die Antwort zu geben ... Ich konnte tatsächlich Hunderte von Fragen eingeben und mich selbst beantworten; das ist nicht der Punkt!
Seb

5
@Seb: Ich bin anderer Meinung. Ich sehe nichts falsch mit dieser Frage. Es war offensichtlich keine extrem einfache Frage, und jetzt kennt er einen besseren Weg als zuvor!
Michael Myers

3
Es war eine echte Frage, aber ich habe die Antwort selbst gefunden, nachdem Google zu kurz gekommen war. Stackoverflow gab es zu diesem Zeitpunkt noch nicht. Ich hatte es auf meiner Website veröffentlicht und es hat jemand anderem geholfen, also dachte ich, dass es hier nützlich sein könnte.
Jeremy Stein

Bonus: Und wenn Sie zufällig Ihren eigenen Objekttyp sortieren, können Sie Comparabledie compareToMethode jederzeit implementieren und überschreiben .
Nabster

42

So können Sie es mit den Streams von Java 8 machen:

mySet.stream().sorted().collect(Collectors.toList());

oder mit einem benutzerdefinierten Komparator:

mySet.stream().sorted(myComparator).collect(Collectors.toList());

9

Es ist immer sicher, entweder die Comparator- oder die Comparable-Schnittstelle zu verwenden, um eine Sortierimplementierung bereitzustellen (wenn das Objekt keine String- oder Wrapper-Klasse für primitive Datentypen ist). Als Beispiel für eine Komparatorimplementierung zum Sortieren von Mitarbeitern nach Namen

    List<Employees> empList = new LinkedList<Employees>(EmpSet);

    class EmployeeComparator implements Comparator<Employee> {

            public int compare(Employee e1, Employee e2) {
                return e1.getName().compareTo(e2.getName());
            }

        }

   Collections.sort(empList , new EmployeeComparator ());

Der Komparator ist nützlich, wenn Sie einen unterschiedlichen Sortieralgorithmus für dasselbe Objekt benötigen (z. B. Emp-Name, Emp-Gehalt usw.). Die Single-Mode-Sortierung kann mithilfe der vergleichbaren Schnittstelle für das gewünschte Objekt implementiert werden.


5

Es gibt keine einzige Methode, um das zu tun. Benutze das:

@SuppressWarnings("unchecked")
public static <T extends Comparable> List<T> asSortedList(Collection<T> collection) {
  T[] array = collection.toArray(
    (T[])new Comparable[collection.size()]);
  Arrays.sort(array);
  return Arrays.asList(array);
}

Es gibt auch eine Collections.sort-Funktion, aber ich denke, sie macht das Gleiche. +1 sowieso.
CookieOfFortune

1
Collections.sort verwendet eine Liste als Parameter.
Jeremy Stein

3

Sie können ein Set in ein konvertieren, in ArrayListdem Sie die ArrayListVerwendung sortieren können Collections.sort(List).

Hier ist der Code:

keySet = (Set) map.keySet();
ArrayList list = new ArrayList(keySet);     
Collections.sort(list);

3
TreeSet sortedset = new TreeSet();
sortedset.addAll(originalset);

list.addAll(sortedset);

Dabei ist Originalset = unsortierte Menge und Liste = die zurückzugebende Liste


TreeSet deaktiviert auch die Liste, was zu einem falschen Ergebnis führen kann, wenn Sie dies nicht annehmen.
Anthonymonori

2

@ Jeremy Stein Ich wollte den gleichen Code implementieren. Außerdem wollte ich das Set nach Liste sortieren. Anstatt Set zu verwenden, habe ich Set-Werte in List konvertiert und diese Liste nach der Variablen sortiert. Dieser Code hat mir geholfen,

set.stream().sorted(Comparator.comparing(ModelClassName::sortingVariableName)).collect(Collectors.toList());

0

Ich verwende diesen Code, den ich praktischer finde als die oben akzeptierte Antwort:

List<Thing> thingList = new ArrayList<>(thingSet);
thingList.sort((thing1, thing2) -> thing1.getName().compareToIgnoreCase(thing2.getName()));
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.