2010-11-12 9 views
36

Estoy tratando de ordenar elementos de un conjunto pero no puedo hacerlo hasta ahora. aquí es mi código que estoy tratando de hacerSorting Values ​​of Set

public static void main(String [] args){ 
    Set<String> set=new HashSet<String>(); 
    set.add("12"); 
    set.add("15"); 
    set.add("5"); 
    List<String> list=asSortedList(set); 
} 

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

pero esta u otra manera no funciona ya que su todo el tiempo me da el mismo orden en el que se han llenado 12,15,5

+5

Un 'Mapa' no es un' Conjunto'. ¡Gran diferencia! –

+3

¿Hay alguna razón por la que no utilizó un SortedSet si desea un conjunto ordenado? –

Respuesta

27

Si ordena las cadenas "12", "15" y "5", entonces "5" viene el último porque "5">"1". es decir, el orden natural de Strings no funciona de la manera esperada.

Si desea almacenar cadenas en su lista pero ordenarlas numéricamente, necesitará utilizar un comparador que maneje esto. p.ej.

Collections.sort(list, new Comparator<String>() { 
    public int compare(String o1, String o2) { 
     Integer i1 = Integer.parseInt(o1); 
     Integer i2 = Integer.parseInt(o2); 
     return (i1 > i2 ? -1 : (i1 == i2 ? 0 : 1)); 
    } 
}); 

Además, creo que usted está consiguiendo un poco metido entre Collection tipos. Un HashSet y un HashMap son cosas diferentes.

+0

+1 ... aunque: restar un int de otro durante la comparación podría conducir a un flujo inferior; una comparación explícita sería más segura. – Adamski

+0

@Adamski gracias, se ha revisado el método 'compare' – mikej

+0

' o1 == o2' puede dar lugar a resultados inesperados con Strings no internos. Utilice 'o1.equals (o2)' (también podría hacer 'o1.intern() == o2.intern()' pero eso es horrible) –

0

Debe pasar una instancia de Comparator al método de clasificación, de lo contrario los elementos se ordenarán en su orden natural.

Para más información consultar Collections.sort(List, Comparator)

5

Está utilizando el comparador predeterminado para ordenar una Set<String>. En este caso, eso significa lexicographic order. Lexicográficamente, "12" viene antes de "15", viene antes de "5".

utilizar un Set<Integer>:

Set<Integer> set=new HashSet<Integer>(); 
set.add(12); 
set.add(15); 
set.add(5); 

o utilizar un comparador diferente:

Collections.sort(list, new Comparator<String>() { 
    public int compare(String a, String b) { 
     return Integer.parseInt(a) - Integer.parseInt(b); 
    } 
}); 
54

Utilice un SortedSet (TreeSet es la opción por defecto):

SortedSet<String> set=new TreeSet<String>(); 
set.add("12"); 
set.add("15"); 
set.add("5"); 
List<String> list=new ArrayList<String>(set); 

Ningún código de clasificación adicional necesario.

Oh, veo que quieres un orden de clasificación diferente.Suministrar un comparador para la TreeSet:

new TreeSet<String>(Comparator.comparing(Integer::valueOf)); 

Ahora su TreeSet clasificará cadenas en orden numérico (lo que implica que va a lanzar excepciones si se suministra cadenas no numéricos)

Referencia:

+0

También puede pasar ese 'Comparador' al constructor de' TreeSet' – NamshubWriter

4

utilizar la clase Integer envoltorio en lugar de cuerdas, ya que está haciendo el trabajo duro por usted mediante la implementación de Comparable<Integer>. Entonces java.util.Collections.sort(list); haría el truco.