2010-10-13 17 views
12

¿Cuál es la solución "buena" (y ¿por qué?) Para obtener un List de un Set y ordenada en un Comparator dado?Cómo obtener la lista del conjunto y el comparador

+0

Esta pregunta no está clara. Por ejemplo, puedo obtener una Lista de un Conjunto y un Comparador ignorando el Comparador. Esa es una "buena" solución ... en el sentido de que es más rápida que las soluciones que usan el Comparador. –

+0

@Stephen Actualizo mi pregunta –

+1

¿Estás seguro de que necesitas una lista? Tal vez un SortedSet sería suficiente. –

Respuesta

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

// add stuff 

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

acaba de agregar COllections.sort() después de eso. –

+0

Respuesta incorrecta, esto no funcionará ya que el constructor ArrayList no ordena nada, ni siquiera ha usado su Comparador, entonces, ¿cómo se ordenará? Use Collections.sort() o TreeSet, como en otras respuestas. – iirekm

+0

Han corregido la respuesta para incluir la llamada a ordenar. –

6

Solo protégelo. El ArrayList tiene 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

Esta es la forma de conseguir un List cuando se tiene un Set:

List list = new ArrayList(set); 

No está seguro de lo que se espera que ver con la Comparator. Si el Set está ordenado, la lista contendrá los elementos en orden ordenado.

+1

Obviamente, él espera usar el comparador para obtener una lista ordenada, lo que implica que el conjunto no está ordenado. ¿Para qué otra cosa usarías un comparador? Por lo tanto, debe ir a través de un conjunto ordenado u ordenar la lista después de poblarla. –

+0

@Christoffer Hammarström - u ordenarlo cuando/insertando los elementos uno por uno: tipo de inserción. – Ishtar

+0

@Ishtar: que es lo que sucede si pasas a través de un conjunto ordenado, mi primera sugerencia. –

2

O bien:

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

Suponiendo que se inicia con un conjunto sin ordenar o un conjunto ordenado en un orden diferente, la siguiente es probablemente el asumir más eficiente que necesita una Lista modificable.

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

Si una lista no modificable es aceptable, entonces el siguiente es un poco más rápido:

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

En la primera versión, Collections.sort(...) copias la lista de contenidos a una matriz, ordena la matriz, y copia los elementos ordenados volver a la lista. La segunda versión es más rápida porque no necesita copiar los elementos ordenados.

Pero para ser sincero, la diferencia de rendimiento probablemente no sea significativa. De hecho, a medida que los tamaños de los conjuntos de entrada se hacen más grandes, el rendimiento estará dominado por el tiempo O(NlogN) para hacer la clasificación. Los pasos de copia son O(N) y su importancia va disminuyendo a medida que N crece.

+0

Su versión con Arrays.sort de hecho no optimiza mucho (o incluso nada), porque Collections.sort() ya contiene código similar: Objeto [] a = list.toArray(); Arrays.sort (a, (Comparador) c); ListIterator i = list.listIterator(); for (int j = 0; j iirekm

+0

@iirekm - utilizando 'Arrays.asList (array)' evita la copia realizada con el iterador de la lista. –

+0

Aaah, tal copia adicional puede ser importante solo para conjuntos de datos muy grandes. – iirekm

Cuestiones relacionadas