2010-11-12 12 views
36

Próbuję posortować elementy zestawu, ale nie można tego zrobić. tutaj jest mój kod, który próbuję zrobićSortowanie wartości zestawu

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

ale ten lub inny sposób nie działa, ponieważ jego cały czas daje mi taką samą kolejność, w jakiej zostały one wypełnione 12,15,5

+5

"Mapa" to nie "Zestaw". Duża różnica! –

+3

Czy istnieje jakiś powód, dla którego nie użyłeś zestawu SortedSet, jeśli chcesz posortować zestaw? –

Odpowiedz

27

Jeśli posortujesz ciągi znaków "12", "15" i "5", wówczas "5" pojawia się jako ostatni, ponieważ "5">"1". tj. naturalna kolejność Strings nie działa tak, jak oczekujesz.

Jeśli chcesz przechowywać ciągi na liście, ale sortuj je numerycznie, musisz użyć komparatora, który to obsługuje. na przykład

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

Także myślę, że są coraz nieco pomieszane między Collection typów. A HashSet i HashMap to różne rzeczy.

+0

+1 ... though: odjęcie jednego int od drugiego podczas porównania może doprowadzić do niedomiaru; jednoznaczne porównanie byłoby bezpieczniejsze. – Adamski

+0

@Adamski dzięki, zrewidowali metodę "porównywania" – mikej

+0

'o1 == o2' może prowadzić do nieoczekiwanych wyników z nie internowanymi Ciągami. Użyj 'o1.equals (o2)' (możesz również zrobić 'o1.intern() == o2.intern()' ale to jest okropne) –

0

Musisz przekazać do instancji Komparator do metody sortowania, w przeciwnym razie elementy zostaną posortowane w ich naturalnej kolejności.

Aby uzyskać więcej informacji sprawdź Collections.sort(List, Comparator)

5

używasz domyślnego komparatora posortować Set<String>. W tym przypadku oznacza to lexicographic order. Leksykograficznie, "12" jest przed "15", występuje przed "5".

Albo użyć Set<Integer>:

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

lub użyj innego komparatora:

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

Użyj SortedSet (TreeSet jest domyślny):

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

No dodatkowy kod sortowania potrzebne.

Och, widzę, że chcesz inną kolejność sortowania.Dostarczamy komparator do TreeSet:

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

Teraz twój TreeSet będą sortować ciągów w kolejności numerycznej (co oznacza, że ​​będzie ona rzucać wyjątki, jeśli dostarczy ciągi nienumeryczne)

referencyjny:

+0

Można również przekazać, że 'Comparator' do konstruktora' TreeSet' – NamshubWriter

4

użyć klasy Integer wrapper zamiast String ponieważ robi ciężkiej pracy dla Ciebie poprzez wdrożenie Comparable<Integer>. Wtedy java.util.Collections.sort(list); załatwiłoby sprawę.

Powiązane problemy