【问题标题】:How to get the 3 highest values in a HashMap?如何获得 HashMap 中的 3 个最高值?
【发布时间】:2020-09-16 12:54:21
【问题描述】:

我有一个如下的哈希图:

    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"

谢谢。

【问题讨论】:

  • 找到最大值,删除并重复两次?
  • 迭代在 for 循环中设置的值。
  • 如果你想订购你不应该首先使用哈希映射。使用有序映射,例如TreeMap

标签: java sorting hashmap entryset


【解决方案1】:

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

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

希望对你有帮助

【讨论】:

  • 这适用于相对较小的输入地图(
  • @Daniel here you go
【解决方案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,头部始终为最大/最小值)。

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

【讨论】:

    【解决方案3】:

    这是我的看法:它只跟踪 TreeSet 中的前 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]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-06
      • 2014-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多