2010-06-19 15 views
5

Powiel możliwe:
How to sort a Map<Key, Value> on the values in Java?Sortowanie HashMap na podstawie wartości, a następnie klucza?

Mam HashMap typu:

HashMap<String, Integer> h = new HashMap<String, Integer>(); 

HashMap zawiera listę łańcuchów i Integer jest licznik dla liczba razy, gdy znaleziono łańcuch. To, co chciałbym móc zrobić, to posortować HashMap na podstawie liczb całkowitych, a następnie w kolejności alfabetycznej ciągów.

W tej chwili jestem ewidencjonowanie największego wystąpienia wyrazu (zmienna o nazwie max) i wyświetlania wartości w następujący sposób:

public void print(){ 
    while(max > 0){ 
     for (String key : h.keySet()){ 
      if(h.get(key) == max){ 
       System.out.println(key + " " + h.get(key)); 
      } 
     } 
     max--; 
    } 
} 

Co nie sortować alfabetycznie wartości, to również dostęp HashMap max * h (rozmiar) razy.

Jakie jest lepsze rozwiązanie?

+0

@krock good find. Tak, dokładnie to samo pytanie. – cletus

Odpowiedz

3

Spójrz na Google Guava libraries. Ma numer Multiset, który wykonuje obliczenia dla ciebie, a następnie masz klasę Ordering, która upraszcza sortowanie.

Wszystko, co musisz zrobić, to wypełnić ciągi za pomocą Multiset. Będzie utrzymywać częstotliwość dla ciebie. Następnie możesz sortować te struny za pomocą Ordering.

1

Prawdopodobnie nie jest to najbardziej eleganckie rozwiązanie, ale co z tym?

//TreeSet with reversed natural ordering (big integers first) 
Map<Integer, Set<String>> h = 
    new TreeMap<Integer, Set<String>>(Collections.reverseOrder()); 
//and use TreeSet for the set... 
// ...  
// 
for(Map.Entry<Integer,Set<String>> entry : h.entrySet()){ 
    for(String str : entry.getValue()){ 
     System.out.println(str + " has occured " + entry.getKey() + " times."); 
    } 
} 
+1

'-1 * o1.compareTo (o2)' jest błędne. Rozważmy przypadek, w którym 'compareTo' zwraca' Integer.MIN_VALUE'. –

+0

@ Stephen: Dzięki za wskazanie! –

+0

Właściwie nie powinienem był napisać własnego kodu do odwrócenia porządku naturalnego: P Zastępując metodą 'Collections.reverseOrder()' .. –

8

Oto Comparator że sortuje Map.Entry obiektów z Comparable kluczy i wartości:

public class ValueThenKeyComparator<K extends Comparable<? super K>, 
            V extends Comparable<? super V>> 
    implements Comparator<Map.Entry<K, V>> { 

    public int compare(Map.Entry<K, V> a, Map.Entry<K, V> b) { 
     int cmp1 = a.getValue().compareTo(b.getValue()); 
     if (cmp1 != 0) { 
      return cmp1; 
     } else { 
      return a.getKey().compareTo(b.getKey()); 
     } 
    } 

} 

którą można umieścić wszystkie wpisy map na liście, a następnie sortowania że:

List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(h.entrySet()); 
Collections.sort(list, new ValueThenKeyComparator<String, Integer>()); 
+0

Prawie, myślę, ponieważ dlatego, że słowa z mniejszą liczbą wystąpień są na pierwszym miejscu. –

-2

możesz użyć interfejsu SortedMap, aby posortować swoją HashMap. To bardzo proste - Automatyczne sortowanie. Patrz: http://java.sun.com/j2se/1.4.2/docs/api/java/util/SortedMap.html. Nie uwzględniłem tutaj żadnego kodu, ale jeśli potrzebujesz, po prostu dodaj komentarz. Dam ci przykładowy kod.

+1

- 1, SortedMap sortuje według klucza, a nie według wartości – whiskeysierra

+0

Mapa, która dodatkowo gwarantuje, że będzie w kolejności rosnącej, posortowana według naturalnej kolejności jego kluczy (patrz interfejs porównywalny) lub przez komparator dostarczony na posortowanej mapie czas utworzenia – Vishal

Powiązane problemy