You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java 8+中收集Map中最大值对应的所有键到List

Java 8+ 收集Map中所有对应最大值的键到List

方法一:两次遍历(简洁直观)

先获取Map中的最大值,再过滤出所有值等于该最大值的键,这是最容易理解和实现的方式:

final Map<String, Integer> map = new HashMap<>();
map.put("first", 50);
map.put("second", 10);
map.put("third", 50);

// 获取最大值,处理空Map的情况
Integer maxValue = map.values().stream()
    .max(Integer::compareTo)
    .orElse(null);

// 过滤所有值等于最大值的键
List<String> maxKeys = map.entrySet().stream()
    .filter(entry -> maxValue != null && entry.getValue().equals(maxValue))
    .map(Map.Entry::getKey)
    .collect(Collectors.toList());

System.out.println(maxKeys); // 输出 [first, third]

如果Map为空,maxValue会是null,此时过滤后的结果是空列表,符合预期。


方法二:一次遍历(适合大数据量)

如果Map数据量很大,不想做两次遍历,可以用reduce操作在一次遍历中同时跟踪最大值和对应的键列表:

final Map<String, Integer> map = new HashMap<>();
map.put("first", 50);
map.put("second", 10);
map.put("third", 50);

List<String> maxKeys = map.entrySet().stream()
    .reduce(
        // 初始值:空列表 + 最小整数
        new AbstractMap.SimpleEntry<>(Collections.emptyList(), Integer.MIN_VALUE),
        (acc, entry) -> {
            int currentVal = entry.getValue();
            if (currentVal > acc.getValue()) {
                // 当前值更大,更新为仅包含当前键的列表
                return new AbstractMap.SimpleEntry<>(Collections.singletonList(entry.getKey()), currentVal);
            } else if (currentVal == acc.getValue()) {
                // 当前值等于最大值,添加到列表
                List<String> updatedList = new ArrayList<>(acc.getKey());
                updatedList.add(entry.getKey());
                return new AbstractMap.SimpleEntry<>(updatedList, currentVal);
            } else {
                // 当前值更小,保留原有结果
                return acc;
            }
        },
        // 并行流场景下的合并逻辑:合并两个结果,取最大值对应的列表
        (acc1, acc2) -> {
            if (acc1.getValue() > acc2.getValue()) {
                return acc1;
            } else if (acc1.getValue() < acc2.getValue()) {
                return acc2;
            } else {
                List<String> mergedList = new ArrayList<>(acc1.getKey());
                mergedList.addAll(acc2.getKey());
                return new AbstractMap.SimpleEntry<>(mergedList, acc1.getValue());
            }
        }
    )
    .getKey();

System.out.println(maxKeys); // 输出 [first, third]

这种方式只遍历一次Map,但代码相对复杂,适合对性能要求较高的场景。


方法三:分组后取最大组

先按值对键进行分组,再找到值最大的分组对应的键列表:

final Map<String, Integer> map = new HashMap<>();
map.put("first", 50);
map.put("second", 10);
map.put("third", 50);

// 按值分组,key是数值,value是对应键的列表
Map<Integer, List<String>> valueGrouped = map.entrySet().stream()
    .collect(Collectors.groupingBy(
        Map.Entry::getValue,
        Collectors.mapping(Map.Entry::getKey, Collectors.toList())
    ));

// 找到最大的数值对应的键列表
List<String> maxKeys = valueGrouped.entrySet().stream()
    .max(Map.Entry.comparingByKey())
    .map(Map.Entry::getValue)
    .orElse(Collections.emptyList());

System.out.println(maxKeys); // 输出 [first, third]

这种方式逻辑清晰,适合需要多次基于值查询键的场景,但会额外创建分组Map,内存开销略大。


内容的提问来源于stack exchange,提问作者Remo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 08:01:28