2010-10-13 20 views
12

Qual è la soluzione "buona" (e perché?) Per ottenere uno List da un Set e ordinato rispetto a un dato Comparator?Come ottenere l'elenco da Set e Comparatore

+0

Questa domanda non è chiara. Ad esempio, posso ottenere una lista da un set e un comparatore ignorando il comparatore. Questa è una "buona" soluzione ... nel senso che è più veloce delle soluzioni che usano il Comparatore. –

+0

@Stephen Ho aggiornato la mia domanda –

+1

Sei sicuro di aver bisogno di una lista? Forse un SortedSet farebbe. –

risposta

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

// add stuff 

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

appena aggiunto COllections.sort() dopo quello. –

+0

Risposta errata, questo non funzionerà in quanto il costruttore ArrayList non ordina nulla, non hai nemmeno usato il tuo Comparatore, quindi come sarà risolto? Utilizzare Collections.sort() o TreeSet, come in altre risposte. – iirekm

+0

Hai risolto la risposta per includere la chiamata per ordinare. –

6

Costruirlo. Il ArrayList ha un constructor taking another Collection.

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

Questo è come ottenere un List quando si ha un Set:

List list = new ArrayList(set); 

Non sei sicuro di quello che ci si aspetta di fare con il Comparator. Se lo Set è ordinato, l'elenco conterrà gli elementi ordinati.

+1

Ovviamente si aspetta di usare il comparatore per ottenere una lista ordinata, il che implica che il set non è ordinato. Per che altro vorresti usare un comparatore? Quindi dovrebbe passare attraverso un set ordinato o ordinare l'elenco dopo averlo popolato. –

+0

@Christoffer Hammarström - o ordinarlo quando/inserendo gli elementi uno ad uno: inserimento sort. – Ishtar

+0

@Ishtar: che cosa succede se si passa attraverso un set ordinato, il mio primo suggerimento. –

2

O:

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

o:

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

Supponendo che si avvia con un insieme non ordinato o un set ordinato in un ordine diverso, il seguente è probabilmente la assumendo più efficiente che hai bisogno di una lista modificabile.

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

Se un elenco non modificabile è accettabile, allora il seguente è un po 'più veloce:

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

Nella prima versione, Collections.sort(...) Copia l'elenco contenuto a un array, ordina l'array e copia i elementi ordinati di nuovo alla lista. La seconda versione è più veloce perché non ha bisogno di copiare gli elementi ordinati.

Ma a dire il vero la differenza di prestazioni non è probabilmente significativa. Infatti, man mano che le dimensioni del set di input aumentano, le prestazioni saranno dominate dal tempo O(NlogN) per eseguire l'ordinamento. I passaggi di copia sono O(N) e ridurranno di importanza man mano che N cresce.

+0

La tua versione con Arrays.sort infatti non ottimizza molto (o anche nulla), perché Collections.sort() contiene già codice simile: Object [] a = list.toArray(); Arrays.sort (a, (Comparatore) c); ListIterator i = list.listIterator(); per (int j = 0; j iirekm

+0

@iirekm - l'uso di 'Arrays.asList (array)' evita la copia eseguita utilizzando l'iteratore di lista. –

+0

Aaah, tale copia aggiuntiva può essere importante solo per i set di dati molto grandi. – iirekm

Problemi correlati