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

Java Streams:将Map按大写Key分组并合并List<Employee>值

解决Map键转大写并合并值列表的问题

方法一:使用Java 8+ Stream API(推荐)

如果你的项目使用Java 8及以上版本,Stream API可以简洁实现需求,避免嵌套列表和类型混乱:

Java 8兼容写法

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

public class Employee {
    private String id;
    private String name;

    public Employee(String id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Employee{" + "id='" + id + '\'' + ", name='" + name + '\'' + '}';
    }

    public static void main(String[] args) {
        // 构建原始分组Map
        Map<String, List<Employee>> originalMap = new HashMap<>();
        originalMap.put("dept1", Arrays.asList(new Employee("1", "Alice"), new Employee("2", "Bob")));
        originalMap.put("Dept1", Arrays.asList(new Employee("3", "Charlie")));
        originalMap.put("dept2", Arrays.asList(new Employee("4", "David")));

        // 转换键为大写并合并员工列表
        Map<String, List<Employee>> resultMap = originalMap.entrySet().stream()
                // 将每个分组的员工拆分为「大写键-单个员工」的条目
                .flatMap(entry -> entry.getValue().stream()
                        .map(emp -> new AbstractMap.SimpleEntry<>(entry.getKey().toUpperCase(), emp)))
                // 按大写键分组,收集对应员工列表
                .collect(Collectors.groupingBy(
                        Map.Entry::getKey,
                        Collectors.mapping(Map.Entry::getValue, Collectors.toList())
                ));

        // 验证结果
        resultMap.forEach((key, emps) -> System.out.println(key + ": " + emps));
    }
}

Java 9+简化写法

Java 9新增了Collectors.flatMapping,可以更直接地合并列表:

Map<String, List<Employee>> resultMap = originalMap.entrySet().stream()
        .collect(Collectors.groupingBy(
                entry -> entry.getKey().toUpperCase(),
                Collectors.flatMapping(entry -> entry.getValue().stream(), Collectors.toList())
        ));

方法二:传统循环实现(兼容低版本Java)

如果项目需要兼容Java 8以下版本,用普通循环更稳妥:

import java.util.*;

public class Employee {
    // 类定义同前...

    public static void main(String[] args) {
        Map<String, List<Employee>> originalMap = new HashMap<>();
        // 初始化原始Map...

        Map<String, List<Employee>> resultMap = new HashMap<>();
        for (Map.Entry<String, List<Employee>> entry : originalMap.entrySet()) {
            String upperKey = entry.getKey().toUpperCase();
            // 不存在则创建新列表,存在则复用已有列表
            List<Employee> targetList = resultMap.computeIfAbsent(upperKey, k -> new ArrayList<>());
            // 合并当前分组的员工列表
            targetList.addAll(entry.getValue());
        }

        // 验证结果
        resultMap.forEach((key, emps) -> System.out.println(key + ": " + emps));
    }
}

问题根源说明

你之前得到Map<Object, List<Object>>且值为嵌套列表,大概率是直接对原Map的entry按大写键分组,但没有将嵌套的List<Employee>拆平,而是直接收集整个列表,导致最终值类型变成List<List<Employee>>,同时因未指定泛型边界,被编译器推断为Object。上面的两种方法都通过拆平列表或直接合并的方式解决了这个问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 04:32:59