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

如何通过Java Streams获取HashMap中第二高值的所有键值对?

使用Java Streams获取Map中第二高值的所有键值对

你的原代码仅能获取单个第二高值的键值对,原因是skip(1).findFirst()只取了排序后的第二个元素,若存在多个值等于第二高的元素,就会遗漏。以下是能获取所有符合条件键值对的解决方案:

方法一:分步获取最大值与第二高值,再过滤收集

import java.util.*;
import java.util.stream.Collectors;

public class SecondHighestMapValues {
    public static void main(String[] args) {
        HashMap<String, Integer> map = new HashMap<>();
        map.put("Pankaj", 1);
        map.put("Amit", 8); // 覆盖之前的2值
        map.put("Rahul", 5);
        map.put("Chetan", 7);
        map.put("Vinod", 6);
        map.put("Rajesh", 7);

        // 1. 获取Map中的最大值
        Optional<Integer> maxVal = map.values().stream()
                .max(Integer::compareTo);

        if (maxVal.isPresent()) {
            // 2. 获取第二高值:所有小于最大值的元素中的最大值
            Optional<Integer> secondMaxVal = map.values().stream()
                    .filter(val -> val < maxVal.get())
                    .max(Integer::compareTo);

            if (secondMaxVal.isPresent()) {
                // 3. 收集所有值等于第二高值的键值对
                List<Map.Entry<String, Integer>> secondMaxEntries = map.entrySet().stream()
                        .filter(entry -> entry.getValue().equals(secondMaxVal.get()))
                        .collect(Collectors.toList());

                // 输出结果
                System.out.println("第二高值为:" + secondMaxVal.get());
                System.out.println("对应的键值对:");
                secondMaxEntries.forEach(entry -> System.out.println(entry.getKey() + ": " + entry.getValue()));
            } else {
                System.out.println("没有第二高值(所有元素值相同)");
            }
        } else {
            System.out.println("Map为空");
        }
    }
}

方法二:按值分组后排序取值

通过将元素按值分组,利用TreeMap自动逆序排序的特性,直接获取第二高值对应的分组:

import java.util.*;
import java.util.stream.Collectors;

public class SecondHighestMapValues {
    public static void main(String[] args) {
        HashMap<String, Integer> map = new HashMap<>();
        map.put("Pankaj", 1);
        map.put("Amit", 8);
        map.put("Rahul", 5);
        map.put("Chetan", 7);
        map.put("Vinod", 6);
        map.put("Rajesh", 7);

        // 按值分组,键为数值(逆序排序),值为对应键值对的列表
        TreeMap<Integer, List<Map.Entry<String, Integer>>> sortedGroups = map.entrySet().stream()
                .collect(Collectors.groupingBy(
                        Map.Entry::getValue,
                        () -> new TreeMap<>(Collections.reverseOrder()),
                        Collectors.toList()
                ));

        // 跳过最大值分组,获取第二高值的分组
        Optional<List<Map.Entry<String, Integer>>> secondMaxEntries = sortedGroups.values().stream()
                .skip(1)
                .findFirst();

        secondMaxEntries.ifPresentOrElse(entries -> {
            System.out.println("第二高值为:" + entries.get(0).getValue());
            System.out.println("对应的键值对:");
            entries.forEach(entry -> System.out.println(entry.getKey() + ": " + entry.getValue()));
        }, () -> {
            System.out.println("没有第二高值(所有元素值相同或Map为空)");
        });
    }
}

说明

  • 方法一逻辑清晰,分步处理,适合理解基础流操作;
  • 方法二利用TreeMap的排序特性,代码更简洁高效;
  • 两种方法都处理了Map为空、所有元素值相同的边界场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 00:35:20