根据值然后键对HashMap进行排序? [复制]

Posted

技术标签:

【中文标题】根据值然后键对HashMap进行排序? [复制]【英文标题】:Sorting a HashMap based on Value then Key? [duplicate] 【发布时间】:2011-03-05 16:29:53 【问题描述】:

可能重复:How to sort a Map<Key, Value> on the values in Java?

我有一个 HashMap 类型:

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

HashMap 包含一个字符串列表,而 Integer 是一个计数器,用于计算找到该字符串的次数。我想做的是根据整数对 HashMap 进行排序,然后根据字符串的字母顺序。

目前我正在记录一个单词的最大出现次数(名为 max 的变量)并显示如下值:

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(size) 次。

什么是更好的解决方案?

【问题讨论】:

@krock 很好的发现。是的,完全相同的问题。 【参考方案1】:

您可以使用 SortedMap 接口对您的 HashMap 进行排序。这很容易 - 自动排序。请参阅http://java.sun.com/j2se/1.4.2/docs/api/java/util/SortedMap.html。我在这里没有包含任何代码,但是如果您需要,只需添加评论即可。我给你一个示例代码。

【讨论】:

-1,SortedMap 按键排序,而不是按值排序 一个地图,进一步保证它将按升序键顺序,根据其键的自然顺序排序(请参阅 Comparable 接口),或通过在排序的地图创建时提供的比较器进行排序跨度> 【参考方案2】:

可能不是最优雅的解决方案,但是这个怎么样?

//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 * o1.compareTo(o2) 有缺陷。考虑compareTo返回Integer.MIN_VALUE的情况。 @Stephen:谢谢指出! 实际上我不应该编写自己的代码来反转自然顺序:P 用Collections.reverseOrder() 方法代替..【参考方案3】:

这是一个Comparator,它使用Comparable 键和值对Map.Entry 对象进行排序:

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

【讨论】:

差不多吧,我猜是因为这样出现次数少的词排在第一位。【参考方案4】:

看看Google Guava libraries。它有一个 Multiset 为您进行计算,然后您有一个简化排序的 Ordering 类。

您需要做的就是用您的字符串填充Multiset。它将为您保持频率。然后您可以使用Ordering 对这些字符串进行排序。

【讨论】:

以上是关于根据值然后键对HashMap进行排序? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何根据值对 HashMap 的元素进行排序? [复制]

按值然后键对字典进行排序

如何创建具有两个键(键对、值)的 HashMap?

通过具有日期值的单个键对对象数组进行排序

如何使用对象的键对对象数组进行排序? [复制]

如何根据日期对 HashMap 进行排序? [复制]