2013-03-15 52 views
6

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

我想要仍然能够知道哪些键具有最高值,地图的K, VString, Integer

+4

你是什么意思的前10名?基于什么? – jsedano 2013-03-15 15:43:59

+0

你可以请张贴一些代码来显示你正在比较什么样的元素? – 2013-03-15 15:44:42

+0

TreeMap可以为你做排序。但为了让我们知道你在尝试分类,你必须告诉我们! – Kevin 2013-03-15 15:45:24

回答

0

恐怕你必须迭代整个地图。 Heap是用于查找顶部K元素的常用数据结构,如this book中所述。

0

如果您想获得地图的10个最高值(假设值是数字或至少实现可比),那么试试这个:

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

这只有在值类型'Foo'实现'可比较的 '而且你不使用原始类型的列表。 – jlordo 2013-03-15 15:52:37

+0

如果OP在他的问题中指定了它,我会放入原始类型:) – aymeric 2013-03-15 15:55:21

2

也许你应该实现Comparable接口你的价值存储在散列映射中的对象。 然后你就可以创建所有值的数组列表:

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

问候

+0

相当好的解决方案。我只需要类似的东西。既然你只是提供价值,但我也需要钥匙。我做了一些细微的修改,并添加了一个比较器来使用入口集。比较器必须按降序比较输入值。 List > results = new ArrayList <>(hashmap.entrySet()); Collections.sort(results,new EntryComparator()); results = results.subList(0,10); – sebadagostino 2017-04-15 22:05:16

+1

我将它添加为另一个答案,因为它看起来不好评论 – sebadagostino 2017-04-15 22:06:13

0

让我们假设你有一个地图,但这个例子可以为任何类型的

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

哦哇,我认为这可能只是做,现在就给它一个镜头,谢谢! – Tohmas 2013-03-15 16:02:01

+0

@Biswajit,你能解释一下这段代码的复杂性吗?你的代码工作正常,而且非常简单,只是想计算这个代码的复杂度。 – Rushi 2015-02-06 00:35:31

+0

@Biswajit,你的代码很棒,但你如何确保TreeMap的大小始终为10?因为你只想要十大权利? 每次将键值对插入Tree Map中时,都需要检查当前大小是否大于10,如果是,则需要删除TreeMap中最小的键 - 值对。你如何在代码中做最后一部分?我不认为人们会在这里回答我的问题,所以我问了一个引用这篇文章的新问题[Here](http://stackoverflow.com/questions/37244198/how-to-maintain-a-java-treemap-size -to待一个添加-恒定而-键 - 值对) – 2016-05-16 16:07:32

0

工作我基于我的答案在这一个从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); 
}