【问题标题】:Get top 10 values in hash map获取哈希图中的前 10 个值
【发布时间】:2013-03-04 09:50:39
【问题描述】:

我想弄清楚如何从HashMap 中获得前 10 个值。我最初尝试使用 TreeMap 并按值排序,然后取前 10 个值,但似乎这不是选项,因为 TreeMap 按键排序。

我希望仍然能够知道哪些键的值最高,映射的K, VString, Integer

【问题讨论】:

  • 前 10 名是什么意思?基于什么?
  • 您能否发布一些代码来显示您正在比较的元素类型?
  • TreeMap 可以为您进行排序。但是为了让我们知道您要按什么排序,您必须告诉我们!
  • 啊抱歉错过了,K,V 是字符串,整数。我仍然需要知道哪些键具有最高值。我尝试过 TreeMap,但它仅按规范中定义的键排序。

标签: java sorting hashmap


【解决方案1】:

我的答案来自sk2212

首先你需要实现一个降序比较器:

class EntryComparator implements Comparator<Entry<String,Integer>> {

    /**
     * Implements descending order.
     */
    @Override
    public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
        if (o1.getValue() < o2.getValue()) {
            return 1;
        } else if (o1.getValue() > o2.getValue()) {
            return -1;
        }
        return 0;
    }

}

然后你可以在一个方法中使用它,比如这个属性“hashmap”:

public List<Entry<String,Integer>> getTopKeysWithOccurences(int top) {
    List<Entry<String,Integer>> results = new ArrayList<>(hashmap.entrySet());
    Collections.sort(results, new EntryComparator());
    return results.subList(0, top);
}

【讨论】:

    【解决方案2】:
    import java.util.Comparator;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.TreeMap;
    
    public class Testing {
    
        public static void main(String[] args) {
    
            HashMap<String,Double> map = new HashMap<String,Double>();
            ValueComparator bvc =  new ValueComparator(map);
            TreeMap<String,Double> sorted_map = new TreeMap<String,Double>(bvc);
    
            map.put("A",99.5);
            map.put("B",67.4);
            map.put("C",67.4);
            map.put("D",67.3);
    
            System.out.println("unsorted map: "+map);
    
            sorted_map.putAll(map);
    
            System.out.println("results: "+sorted_map);
        }
    }
    
    class ValueComparator implements Comparator<String> {
    
        Map<String, Double> base;
        public ValueComparator(Map<String, Double> base) {
            this.base = base;
        }
    
        // Note: this comparator imposes orderings that are inconsistent with equals.    
        public int compare(String a, String b) {
            if (base.get(a) >= base.get(b)) {
                return -1;
            } else {
                return 1;
            } // returning 0 would merge keys
        }
    }
    

    【讨论】:

    • 哦,哇,我想这可能就行了,现在就试一试,谢谢!
    • @Biswajit,你能解释一下这段代码的复杂性吗?您的代码运行良好,而且方法非常简单,只是想计算这段代码的复杂性......
    • @Biswajit,您的代码很棒,但是您如何确保 TreeMap 的大小始终为 10?因为你只想进入前十对吗?每次在Tree Map中插入一个key-value对,都需要检查当前size是否大于10,如果是,则需要删除TreeMap中最小的key-value对。你如何在代码中完成这最后一部分?我不认为人们会在这里回答我的问题,所以我提出了一个新问题,引用了这篇文章 Here
    【解决方案3】:

    假设你有一个地图,但这个例子适用于任何类型的

    Map<String, String> m = yourMethodToGetYourMap();
    List<String> c = new ArrayList<String>(m.values());
    Collections.sort(c);
    for(int i=0 ; i< 10; ++i) {
        System.out.println(i + " rank is " + c.get(i)); 
    }
    

    【讨论】:

      【解决方案4】:

      也许您应该为存储在哈希图中的值对象实现Comparable 接口。 然后你可以创建一个包含所有值的数组列表:

      List<YourValueType> l = new ArrayList<YourValueType>(hashmap.values());
      Collection.sort(l);
      l = l.subList(0,10);
      

      问候

      【讨论】:

      • 很好的解决方案。我只是需要类似的东西。由于您只提供值,但我还需要密钥。为了使用入口集,我做了一点修改并添加了一个比较器。比较器必须按降序比较输入值。 List> results = new ArrayList(hashmap.entrySet()); Collections.sort(results, new EntryComparator());结果 = results.subList(0, 10);
      • 我将其添加为另一个答案,因为它看起来不好作为评论
      【解决方案5】:

      如果您尝试获取地图的 10 个最高值(假设值是数字或至少实现 Comparable),请尝试以下操作:

      List list = new ArrayList(hashMap.values());
      Collections.sort(list);
      for(int i=0; i<10; i++) {
         // Deal with your value
      }
      

      【讨论】:

      • 这只有在值类型 Foo 实现 Comparable&lt;Foo&gt; 并且您不使用原始类型的列表时才有效。
      • 如果 OP 在他的问题中指定了原始类型,我会输入原始类型 :)
      【解决方案6】:

      恐怕您将不得不遍历整个地图。 Heap 是一种常用的数据结构,用于查找前 K 个元素,如 this book 中所述。

      【讨论】:

        猜你喜欢
        • 2016-05-26
        • 2017-02-16
        • 2013-01-09
        • 1970-01-01
        • 2012-02-11
        • 2016-07-22
        • 1970-01-01
        • 2012-06-21
        • 1970-01-01
        相关资源
        最近更新 更多