有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在HashMap中获得3个最高值?

我有一个hashmap,如下所示:

    HashMap<String, Integer> hm = new HashMap<String, Integer>;
    hm.put("a", 1);
    hm.put("b", 12);
    hm.put("c", 53);
    hm.put("d", 2);
    hm.put("e", 17);
    hm.put("f", 8);
    hm.put("g", 8);

如何获取具有3个最高值的键?因此,它将返回:

    "c", "e", "b"

谢谢


共 (3) 个答案

  1. # 1 楼答案

    我的看法是:这只跟踪树集中的前n个项目

    import java.util.*;
    import java.util.stream.Collectors;
    
    public class TopN {
        public static <E> Collection<E> topN(Iterable<E> values, Comparator<? super E> comparator, int n) {
            NavigableSet<E> result = new TreeSet<>(comparator.reversed());
            for (E value : values) {
                result.add(value);
                if (result.size() > n) {
                    result.remove(result.last());
                }
            }
            return result;
        }
    
        public static void main(String[] args) {
            Map<String, Integer> hm = Map.of(
                    "a", 1,
                    "b", 12,
                    "c", 53,
                    "d", 2,
                    "e", 17,
                    "f", 8,
                    "g", 8);
    
            List<String> result = topN(hm.entrySet(), Map.Entry.comparingByValue(), 3)
                    .stream()
                    .map(Map.Entry::getKey)
                    .collect(Collectors.toList());
            System.out.println(result);
        }
    }
    

    最后的输出是[c, e, b]

  2. # 2 楼答案

    这很难阅读,但会表现得更好:

     public static List<String> firstN(Map<String, Integer> map, int n) {
        PriorityQueue<Entry<String, Integer>> pq = new PriorityQueue<>(
            n + 1, Map.Entry.comparingByValue()
        );
    
        int bound = n + 1;
        for (Entry<String, Integer> en : map.entrySet()) {
            pq.offer(en);
            if (pq.size() == bound) {
                pq.poll();
            }
        }
    
        int i = n;
        String[] array = new String[n];
        while ( i >= 0) {
            array[i] = pq.remove().getKey();
        }
        return Arrays.asList(array);
    }
    

    如果您知道PriorityQueue是如何工作的,那么这相当简单:它在任何给定的时间点只保留n + 1元素。在添加元素时,将逐个删除最小的元素

    完成此操作后,我们将元素插入数组,但顺序相反(因为PriorityQueue只对其头部进行排序,或者根据Comparator将头部始终为max/min)

    您甚至可以将其设置为通用的,或者为此创建带有流的自定义收集器

  3. # 3 楼答案

    我的解决方案,按值排序,获得前3名并返回键列表

    List<String> keys = hm.entrySet().stream().sorted(Map.Entry.<String, Integer>comparingByValue().reversed()).limit(3).map(Map.Entry::getKey).collect(Collectors.toList());
    
    

    希望能有帮助