¿Cómo clasifico un conjunto en una lista en Java?

169

En Java, tengo un Set, y quiero convertirlo en un ordenado List. ¿Hay algún método en el java.util.Collectionspaquete que haga esto por mí?

Jeremy Stein
fuente

Respuestas:

214

La respuesta proporcionada por el OP no es la mejor. Es ineficiente, ya que crea un nuevo List y matriz innecesaria. Además, genera advertencias "no verificadas" debido a los problemas de seguridad de tipo en torno a las matrices genéricas.

En cambio, use algo como esto:

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;
}

Aquí hay un ejemplo de uso:

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);
erickson
fuente
3
¡Gracias! Ese SuppressWarnings siempre me molestó.
Jeremy Stein el
44
@sunleo La Utilclase es la que contiene el asSortedList()método que escribí. En otras palabras, usted escribe la Utilclase usted mismo y le agrega ese código.
erickson
1
ja, ja, pensé que es del paquete predeterminado como java.util ok, gracias.
sunleo
3
Esta podría ser una buena función genérica de utilidad, pero el hecho es que todavía no es eficiente. Para comenzar, considere la clasificación in situ asegurándose de tener su conjunto en el contenedor correcto. También considere el uso del TreeSet como un contenedor directo de sus datos. Si sus datos deben ser únicos de todos modos, y necesita un Set, entonces use el TreeSet, atrapa dos moscas en un golpe.
YoYo
1
Como una nota para las personas que solo leen la respuesta principal: Eche un vistazo a la respuesta de nschum a continuación, que utiliza las secuencias de Java 8. Si puede usar Java 8, hágalo. Son más flexibles y eficientes.
Felk
74

Conjunto ordenado:

return new TreeSet(setIWantSorted);

o:

return new ArrayList(new TreeSet(setIWantSorted));
Steve B.
fuente
Este fue mi primer pensamiento, pero el autor de la pregunta quería una lista
Alex B
@Alex: este enfoque todavía se puede utilizar; return new ArrayList (new TreeSet (setIWantSorted))
Jonik
1
De hecho, utilicé esta solución, pero no lo recomendaría. Como dice la documentación sobre TreeSet (consulte download.oracle.com/javase/1.4.2/docs/api/java/util/… ), utiliza efectivamente el método compareTo () en lugar del método equals (), así que si tienen dos objetos en el conjunto que tienen el mismo resultado igual (), se verán como duplicados y, como tales, no se agregarán al TreeSet. Tener cuidado.
fwielstra
24
@fwielstra: ¿Cómo puedes tener objetos que sean iguales en la entrada ya que la entrada también es un Set?
ryanprayogo
2
@ryanprayogo Vale la pena mencionar, ya que new TreeSetacepta Collections, no solo Sets. No todos los que lean esta respuesta usarán un Set, a pesar de que esa es la pregunta original.
Chris
44
List myList = new ArrayList(collection);
Collections.sort(myList);

... Sin embargo, debería hacer el truco. Agregue sabor con genéricos cuando corresponda.

Esko
fuente
Tenía un fragmento útil que quería donar a la comunidad. Cuando busqué la información, no pude encontrarla. Estaba tratando de facilitar el trabajo de la siguiente persona. stackoverflow.com/questions/18557/…
Jeremy Stein
1
Sí, claro, pero ese enlace que proporcionó en realidad está hablando de preguntas reales (es decir, aquellas para las que no tiene la respuesta, luego encuéntrela). Su pregunta aquí fue solo para dar la respuesta ... En realidad, podría ingresar cientos de preguntas y responderme; ¡ese no es el punto!
Seb
55
@Seb: no estoy de acuerdo. No veo nada malo con esta pregunta. Obviamente no era una pregunta extremadamente simple, ¡y ahora él conoce una mejor manera que antes!
Michael Myers
3
Que era una cuestión real, pero he encontrado la respuesta a mí mismo después de que Google se quedó corto. Stackoverflow no existía en ese momento. Lo publiqué en mi sitio web y ayudó a alguien más, así que pensé que podría ser útil aquí.
Jeremy Stein el
Bonificación: Y si está ordenando su propio tipo de objeto, siempre puede implementar Comparabley anular el compareTométodo.
Nabster
42

Así es como puedes hacerlo con las transmisiones de Java 8:

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

o con un comparador personalizado:

mySet.stream().sorted(myComparator).collect(Collectors.toList());
nschum
fuente
9

Siempre es seguro usar la interfaz Comparador o Comparable para proporcionar una implementación de clasificación (si el objeto no es una clase String o Wrapper para tipos de datos primitivos). Como ejemplo para una implementación de comparación para clasificar a los empleados según su nombre

    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 ());

El comparador es útil cuando necesita tener un algoritmo de clasificación diferente en el mismo objeto (diga nombre emp, salario emp, etc.). La ordenación de modo único se puede implementar mediante el uso de una interfaz comparable en el objeto requerido.

Satheesh Cheveri
fuente
5

No hay un método único para hacer eso. Utilizar este:

@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);
}
Jeremy Stein
fuente
También hay una función Collections.sort, pero creo que hace lo mismo. +1 de todos modos.
CookieOfFortune
1
Collections.sort toma una lista como parámetro.
Jeremy Stein
3

Puede convertir un conjunto en un ArrayList, donde puede ordenar el ArrayListusoCollections.sort(List) .

Aquí está el código:

keySet = (Set) map.keySet();
ArrayList list = new ArrayList(keySet);     
Collections.sort(list);
Amit
fuente
3
TreeSet sortedset = new TreeSet();
sortedset.addAll(originalset);

list.addAll(sortedset);

donde originalset = conjunto sin clasificar y list = la lista que se devolverá

Sujith Mohan
fuente
TreeSet también elimina la lista, lo que puede dar como resultado un resultado incorrecto si no asume eso.
anthonymonori
2

@ Jeremy Stein Quería implementar el mismo código. Además, quería ordenar el conjunto de la lista, por lo que en lugar de usar el conjunto, convertí los valores del conjunto en Lista y clasifiqué esa lista por una variable. Este código me ayudó

set.stream().sorted(Comparator.comparing(ModelClassName::sortingVariableName)).collect(Collectors.toList());
Deepak Kumbhar
fuente
0

Estoy usando este código, que me parece más práctico que la respuesta aceptada anteriormente:

List<Thing> thingList = new ArrayList<>(thingSet);
thingList.sort((thing1, thing2) -> thing1.getName().compareToIgnoreCase(thing2.getName()));
nn4l
fuente