2010-10-13 8 views
12

Was ist die "gute" (und warum?) Lösung, um eine List von einem Set und sortiert nach einer gegebenen Comparator?How get Liste von Set und Komparator

+0

Diese Frage ist unklar. Zum Beispiel kann ich eine Liste von einem Set und einem Comparator bekommen, indem ich den Comparator ignoriere. Das ist eine "gute" Lösung ... in dem Sinne, dass es schneller ist als Lösungen, die den Comparator verwenden. –

+0

@Stephen Ich aktualisiere meine Frage –

+1

Sind Sie sicher, dass Sie eine Liste benötigen? Vielleicht würde ein SortedSet tun. –

Antwort

11
Set<Object> set = new HashSet<Object>(); 

// add stuff 

List<Object> list = new ArrayList<Object>(set); 
Collections.sort(list, new MyComparator()); 
+0

gerade hinzugefügt COllections.sort() danach. –

+0

Falsche Antwort, dies wird nicht funktionieren, da ArrayList-Konstruktor nichts sortiert, Sie haben nicht einmal Ihren Komparator verwendet, also wie wird er sortiert? Verwenden Sie entweder Collections.sort() oder TreeSet wie in anderen Antworten. – iirekm

+0

Haben Sie die Antwort korrigiert, um den Aufruf zum Sortieren einzuschließen. –

6

Konstruieren Sie es einfach. Die ArrayList hat eine constructor taking another Collection. Diese

Set<Foo> set = new TreeSet<Foo>(new FooComparator<Foo>()); 
// Fill it. 

List<Foo> list = new ArrayList<Foo>(set); 
// Here's your list with items in the same order as the original set. 
0

ist, wie man eine List erhalten, wenn Sie eine Set:

List list = new ArrayList(set); 

nicht sicher, was Sie mit dem Comparator zu tun erwarten. Wenn die Set sortiert ist, enthält die Liste die Elemente in sortierter Reihenfolge.

+1

Offensichtlich erwartet er, den Komparator zu verwenden, um eine sortierte Liste zu erhalten, was impliziert, dass der Satz unsortiert ist. Wozu sonst würden Sie einen Komparator verwenden? Also sollte er entweder über eine sortierte Menge gehen oder die Liste nach dem Auffüllen sortieren. –

+0

@Christoffer Hammarström - oder sortieren Sie es wenn/durch Einfügen der Elemente nacheinander: Insertion sort. – Ishtar

+0

@Ishtar: Was passiert, wenn du über einen sortierten Satz gehst, mein erster Vorschlag. –

2

Entweder:

Set<X> sortedSet = new TreeSet<X>(comparator); ... 
List<X> list = new ArrayList<X>(sortedSet); 

oder:

Set<X> unsortedSet = new HashSet<X>(); ... 
List<X> list = new ArrayList<X>(unsortedSet); 
Collections.sort(list, comparator); 
1

Unter der Annahme, dass Sie mit einer unsortierten Satz oder einem Satz auf einer anderen Reihenfolge sortiert beginnen, ist die folgende wahrscheinlich die effizienteste unter der Annahme, dass Sie eine änderbare Liste benötigen.

Set<T> unsortedSet = ... 
List<T> list = new ArrayList<T>(unsortedSet); 
Collections.sort(list, comparator); 

Wenn eine unveränderbare Liste akzeptabel ist, dann wird die folgende ist ein bisschen schneller:

Set<T> unsortedSet = ... 
T[] array = new T[unsortedSet.size()]; 
unsortedSet.toArray(array); 
Arrays.sort(array, comparator); 
List<T> list = Arrays.asList(array); 

In der ersten Version Collections.sort(...) kopiert die Listeninhalte auf ein Array, sortiert das Array und kopiert die sortierte Elemente zurück zur Liste. Die zweite Version ist schneller, da die sortierten Elemente nicht kopiert werden müssen.

Aber um ehrlich zu sein, ist der Leistungsunterschied wahrscheinlich nicht signifikant. In der Tat wird die Leistung, wenn die Größen der Eingabesätze größer werden, durch die Zeit O(NlogN) für die Sortierung dominiert. Die Kopierschritte sind O(N) und werden mit wachsendem N kleiner.

+0

Ihre Version mit Arrays.sort optimiert tatsächlich nicht viel (oder gar nichts), da Collections.sort() bereits ähnlichen Code enthält: Object [] a = list.toArray(); Arrays.sort (a, (Komparator) c); ListIterator i = list.listIterator(); für (int j = 0; j iirekm

+0

@iirekm - mit 'Arrays.asList (Array)' vermeidet das Kopieren mit dem Listen-Iterator. –

+0

Aaah, solch ein zusätzliches Kopieren kann nur für sehr große Datenmengen wichtig sein. – iirekm