如何从HashMap中获取对应最大值的Key?

How to get a Key from HashMap which corresponds to the max value?

我有以下 TreeMap 和给定的 2 个值:

Map<Integer, Integer> map = new TreeMap<>();

// 1 --> 3
// 2 --> 4

我想获取具有最大值的密钥。我通过以下方式获得最大值:

int max = map.values().stream().max(Integer::compare).get();

// 4

但是,我无法根据这个最大值过滤地图键。那么,我怎样才能得到最大值(2)的关键呢?或者 TreeMap 中给定值的键?我使用 TreeMap 而不是 HashMap 以便我可以在需要时对地图进行排序(也许不需要)。

I used TreeMap instead of HashMap so that I can sort the map if needed (maybe not need).

为此,HashMap 就足够了,如果您不将其用于其他用途,则可以将 TreeMap 替换为 HashMap。此外,TreeMap 无法帮助完成此任务,因为维护条目的顺序基于 keys,而不是值(您的这个例子有点误导——max value 被映射到 max key,如果你改变它,TreeMap 将不再有帮助) .

要使用 Stream API 解决此问题,首先,您需要在 条目集 上创建一个流,因为当你只有一个值时你无法访问键。

终端操作max() returns 一个可选的对象,它将保存条目(如果存在结果)。在可选对象上调用的方法 map() 会将 Optional<Map.Entry<Integer, Integer>> 转换为 Optional<Integer>.

方法 orElseThrow() 在这种情况下将是 get() 更好的替代方法。如果可选对象为空,两者都会抛出异常。如果根据您的逻辑,值保证存在,最好用 orElseThrow() 明确指定您的意图是在结果不存在时抛出异常,因为这种情况是异常的。

NavigableMap<Integer, Integer> map = new TreeMap<>();

int maxKey = map.entrySet().stream()
        .max(Map.Entry.comparingByValue()) // Optional<Map.Entry<Integer, Integer>> - entry
        .map(Map.Entry::getKey)            // Optional<Integer> - key
        .orElseThrow();

由于多个键可能具有相同的值,因此 最大值 可能会映射到多个键。在这种情况下,您可能希望获得这些键的列表:

NavigableMap<Integer, Integer> map = new TreeMap<>();

int maxValue = map.entrySet().stream()
        .max(Map.Entry.comparingByValue())
        .map(Map.Entry::getValue)
        .orElseThrow();    
    
List<Integer> maxValues = map.entrySet().stream()
        .filter(entry -> entry.getValue() == maxValue)
        .map(Map.Entry::getKey)
        .collect(Collectors.toList());

旁注:当您使用 TreeMap 并且不要期望可以使用接口 Map 的未排序实现分配变量时,然后使用接口 NavigableMap 作为类型。它将为您提供 getFirstEntry()getFirstKey()higherEntry() 等方法的访问权限,这些方法在 Map.

中不可用

要获得正确的密钥,您可以使用这个:

Optional<Map.Entry<Integer,Integer>> entry = map.entrySet().stream().max(Map.Entry.comparingByValue());
System.out.println(entry.get().getKey());

如果您使用正确的界面,这将非常容易。

NavigableMap<Integer, Integer> map = new TreeMap<>();
return map.lastEntry().getKey();

更重要的是,这比使用任何 Stream 都高效得多。