Java如何根据HashMap中的值返回前10个项目

时间:2013-06-13 19:07:19

标签: java sorting

所以我对Java很陌生,因此我正在通过练习,将我的一个Python程序转换为Java。

我遇到了一个问题,我试图复制行为,从python下面只会返回按键排序的键(而不是值):

popular_numbers = sorted(number_dict, key = number_dict.get, reverse = True)

在Java中,我做了一些研究,还没有找到一个简单的n00b样本,比如我自己或类似的方法。我找到了使用Guava进行排序的示例,但排序似乎返回按键排序的HashMap。

除了上述内容之外,我在Java中找不到的另一个关于Python的好处是能够轻松返回已排序值的子集。在Python中,我可以简单地执行以下操作:

print "Top 10 Numbers: %s" % popular_numbers[:10]

在此示例中,number_dict是键值对的字典,其中key表示数字1..100,值是数字(键)出现的次数:

for n in numbers:
 if not n == '':
   number_dict[n] += 1

最终结果如下:

  

前10位数字:['27','11','5','8','16','25','1','24','32',   '20']

为了澄清,在Java中我成功创建了一个HashMap,我已经成功检查了数字并增加了键值对的值。我现在陷入了排序并根据值返回前10个数字(键)。

9 个答案:

答案 0 :(得分:10)

  1. 将地图的entrySet()放入List
  2. 使用Collections.sortComparator对此列表进行排序,Entry根据其值对subList(int, int)进行排序。
  3. 使用List的{​​{3}}方法检索包含前10个元素的新列表。
  4. 是的,它会比Python更冗长:)

答案 1 :(得分:1)

使用Java 8+,获取一个整数列表的前10个元素:

list.stream().sorted().limit(10).collect(Collectors.toList());

获取地图键的前10个元素,即整数:

map.keySet().stream().sorted().limit(10).collect(Collectors.toMap(Function.identity(), map::get));

答案 2 :(得分:0)

假设您的地图定义如此,并且您希望根据进行排序:

HashMap<Integer, Integer> map= new HashMap<Integer, Integer>();
//add values
Collection<Integer> values= map.values();
ArrayList<Integer> list= new ArrayList<Integer>(values);
Collections.sort(list);

现在,打印列表的前10个元素。

for (int i=0; i<10; i++) {
    System.out.println(list.get(i));
}

映射中的值实际上没有排序,因为HashMap根本没有排序(它根据键的hashCode将值存储在存储桶中)。此代码只显示地图中的10个最小元素。

编辑排序而不会丢失键值对:

//sorted tree map
TreeMap<Integer, Integer> tree= new TreeMap<>();

//iterate over a map
Iteartor<Integer> it= map.keySet().iterator();
while (it.hasNext()) {
    Integer key= it.next();
    tree.put(map.get(key), key);
}

现在,您拥有已排序的TreeMap树,并且已从原始地图中反转了键值对,因此您不会丢失信息。

答案 3 :(得分:0)

HashMap不是用Java命令的,因此没有一种好的方法可以通过所有键对它们进行强力搜索。尝试使用TreeMaphttp://docs.oracle.com/javase/6/docs/api/java/util/TreeMap.html

答案 4 :(得分:0)

尝试下一个:

public static void main(String[] args) {

    // Map for store the numbers
    Map<Integer, Integer> map = new HashMap<Integer, Integer>();

    // Populate the map ...

    // Sort by the more popular number
    Set<Entry<Integer, Integer>> set = map.entrySet();
    List<Entry<Integer, Integer>> list = new ArrayList<>(set);
    Collections.sort(list, new Comparator<Entry<Integer, Integer>>() {
        @Override
        public int compare(Entry<Integer, Integer> a,
                Entry<Integer, Integer> b) {
            return b.getValue() - a.getValue();
        }
    });


    // Output the top 10 numbers
    for (int i = 0; i < 10 && i < list.size(); i++) {
        System.out.println(list.get(i));
    }

}

答案 5 :(得分:0)

Guava Multiset非常适合您的用例,并且可以很好地替换您的HashMap。它是一个计算每个元素出现次数的集合。

Multisets有一个方法copyHighestCountFirst,它返回按计数排序的不可变Multiset。

现在有些代码:

Multiset<Integer> counter = HashMultiset.create();
//add Integers 
ImmutableMultiset<Integer> sortedCount = Multisets.copyHighestCountFirst(counter);
//iterate through sortedCount as needed

答案 6 :(得分:0)

使用SortedMap,致电values()。文档表明以下内容:

The collection's iterator returns the values in ascending order of the corresponding keys

只要您的比较器写得正确,您就可以迭代第一个n

答案 7 :(得分:0)

  1. 从键集中建立一个列表。

  2. 使用键将HashMap按值排序,以访问Collection.sort()方法中的值。

  3. 返回已排序键集的子列表。

  4. 如果您关心这些值,则可以使用第3步中的键并建立值集。

    HashMap hashMap =新的HashMap (); 列表列表=新的ArrayList(hashMap.keySet()); Collections.sort(列表,(w1,w2)-> hashMap.get(w2)-hashMap.get(w1)); //按值降序排列;

    return list.subList(0,10);

答案 8 :(得分:0)

为了保持排名顺序并有效地返回顶部计数,远小于地图大小的大小:

map.entrySet().stream()
            .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
            .limit(count)
            .collect(toMap(Map.Entry::getKey, Map.Entry::getValue,
                    (e1, e2) -> e1,
                    LinkedHashMap::new))