31

是否有一种方法(可能使用 Google Collections)来获取 a 的最小值Map(Key, Double)

以传统方式,我必须根据值对地图进行排序,然后取第一个/最后一个。

4

9 回答 9

59

您可以Collections#min()为此使用标准。

Map<String, Double> map = new HashMap<String, Double>();
map.put("1.1", 1.1);
map.put("0.1", 0.1);
map.put("2.1", 2.1);

Double min = Collections.min(map.values());
System.out.println(min); // 0.1

更新:因为您也需要密钥,所以我看不到CollectionsGoogle Collections2API 中的方法,因为 aMap不是Collection. Maps#filterEntries()也不是很有用,因为您只知道迭代结束时的实际结果

最直接的解决方案是:

Entry<String, Double> min = null;
for (Entry<String, Double> entry : map.entrySet()) {
    if (min == null || min.getValue() > entry.getValue()) {
        min = entry;
    }
}

System.out.println(min.getKey()); // 0.1

min左侧为空检查)

于 2010-05-05T19:42:13.287 回答
23

您仍然可以使用Collections.min自定义Comparator来获得Map.Entry较低的值:

Map<String, Double> map = new HashMap<String, Double>();
map.put("1.1", 1.1);
map.put("0.1", 0.1);
map.put("2.1", 2.1);
Entry<String, Double> min = Collections.min(map.entrySet(), new Comparator<Entry<String, Double>>() {
    public int compare(Entry<String, Double> entry1, Entry<String, Double> entry2) {
        return entry1.getValue().compareTo(entry2.getValue());
    }
});
System.out.printf("%s: %f", min.getKey(), min.getValue()); // 0.1: 0.100000

使用 Java 8:

Entry<String, Double> min = Collections.min(map.entrySet(),
                                       Comparator.comparing(Entry::getValue));
于 2010-05-06T17:46:31.997 回答
8

Java8 单线

Key key = Collections.min(map.entrySet(), Map.Entry.comparingByValue()).getKey()
于 2019-05-03T14:47:29.110 回答
5

以传统方式,我必须根据值对地图进行排序,然后取第一个/最后一个。谢谢

不,你不会。您必须遍历所有值,并在每一步将当前元素与迄今为止看到的最小元素进行比较。这是 O(n),与 O(n*log(n)) 进行排序相比 - 一个潜在的巨大差异。

顺便说一句,这正是它的Collections.min()工作原理。

于 2010-05-05T19:46:02.190 回答
4

使用 Java 8 流:

return map
            .entrySet()
            .stream()
            .sorted(Comparator.comparingDouble(Map.Entry::getValue))
            .findFirst()
            .map(Map.Entry::getValue);

或者

return map
            .entrySet()
            .stream()
            .min(Comparator.comparingDouble(Map.Entry::getValue))
            .map(Map.Entry::getValue);

但是如果你想多次这样做,那么一定要给heap看看。

于 2016-07-18T09:00:49.873 回答
2

我倾向于使用 Google Collections BiMap:

     String minKey = HashBiMap.create(map).inverse().get(Collections.min(map.values()));

或类似的东西(未经测试)。

于 2010-05-05T20:15:21.677 回答
2

在 Java 8 中我们可以很容易地得到:

Double minValue = map.entrySet().stream().min(Map.Entry.comparingByValue()).get().getValue();
Double maxValue = map.entrySet().stream().max(Map.Entry.comparingByValue()).get().getValue();
于 2019-01-20T15:18:50.043 回答
1

为了有效地做到这一点,您可能希望定义自己的数据结构,以便它实现 Map 接口,但也允许有效的 getMin() 操作。

这可以使用两种内部数据结构来完成:映射和树(或堆数据结构)。每次添加新对 (K,V) 时,将它们添加到地图和树中(作为单个条目)。这允许 O(1) 时间用于 get(Key) 操作,而 O(log n) 时间用于添加、删除和 getMin 操作。

于 2010-05-05T20:08:45.277 回答
1

使用 java 8(和静态导入)。我们可以让@superfav 的解决方案更加整洁:

Map<String, Double> myMap;
String theKeyWithHighestValue = Collections.min(myMap.entrySet(), comparingDouble(Entry::getValue)).getKey()
于 2016-04-12T04:05:02.103 回答