2010-06-19 3 views
5

Можно создать дубликат:
How to sort a Map<Key, Value> on the values in Java?Сортировка HashMap на основе Value, затем Key?

У меня есть HashMap типа:

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

Метод HashMap содержит список строк и Integer счетчик для количество раз, которое String было найдено. То, что я хотел бы сделать, это сортировать HashMap на основе целых чисел, а затем в алфавитном порядке строк.

На данный момент я храню запись наибольшего вхождения слова (переменная с именем макс) и отображение значения следующим образом:

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

Который не сортирует значения в алфавитном порядке, а также он обращается HashMap max * h (размер) раз.

Какое лучшее решение?

+0

@krock хорошая находка. Да, точно такой же вопрос. – cletus

ответ

3

Посмотрите на Google Guava libraries. Он имеет Multiset, который выполняет расчеты для вас, а затем у вас есть класс Ordering, который упрощает сортировку.

Все, что вам нужно сделать, это заполнить Multiset своими строками. Он будет поддерживать частоту для вас. Затем вы можете сортировать по этим строкам, используя Ordering.

1

Возможно, это не самое элегантное решение, но как насчет этого?

//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)' ошибочен. Рассмотрим случай, когда 'compareTo' возвращает' Integer.MIN_VALUE'. –

+0

@ Стефен: Спасибо за указание! –

+0

На самом деле, я не должен был писать свой собственный код для изменения естественного порядка: P Подставляя метод 'Collections.reverseOrder()'. –

8

Вот Comparator, что сортирует Map.Entry объекты с Comparable ключами и значениями:

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

} 

Вы бы поставить все записи карты в списке, а затем сортировать что:

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

Почти, я думаю, потому что потому, что слова с меньшим количеством появления наступают первыми .. –

-2

вы можете использовать интерфейс SortedMap для сортировки HashMap. Это очень просто - автоматическая сортировка. См. http://java.sun.com/j2se/1.4.2/docs/api/java/util/SortedMap.html. Здесь я не добавил код, но если вам нужно, просто добавьте комментарий. Я дам вам образец кода.

+1

- 1, SortedMap сортирует по ключу, а не по значению – whiskeysierra

+0

Карта, которая далее гарантирует, что она будет в порядке возрастания ключа, отсортирована в соответствии с естественным порядком его ключей (см. Интерфейс Comparable) или компаратором, предоставленным на отсортированной карте время создания – Vishal

Смежные вопросы