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

如何用Java 8 Stream将嵌套集合转为Map<课程ID, List<Student>>

解决Java 8 Stream生成按课程ID分组的学生映射问题

我来帮你搞定这个转换需求!你需要把List<Student>转换成Map<Integer, List<Student>>(键是课程ID,值是选修该课程的学生列表),核心是用flatMap先展开学生和课程的一对多关系,再进行分组。

完整实现代码

首先确保你的Course和Student类已经添加了对应的getter方法(比如getId()、getCourses()),然后可以用以下代码实现:

import java.util.AbstractMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

// 假设你的Student和Course类已定义并添加了getter
public class Main {
    public static void main(String[] args) {
        List<Student> students = ...; // 你的学生集合

        Map<Integer, List<Student>> courseIdToStudents = students.stream()
                // 过滤掉课程列表为空或null的学生,避免空指针异常
                .filter(student -> student.getCourses() != null && !student.getCourses().isEmpty())
                // 展开每个学生的课程,将学生与每门课程关联为Entry(课程ID -> 学生)
                .flatMap(student -> student.getCourses().stream()
                        .map(course -> new AbstractMap.SimpleEntry<>(course.getId(), student)))
                // 按课程ID分组,收集对应的学生列表
                .collect(Collectors.groupingBy(
                        Map.Entry::getKey,
                        Collectors.mapping(Map.Entry::getValue, Collectors.toList())
                ));
    }
}

代码分步解释

  • 过滤环节:filter(student -> student.getCourses() != null && !student.getCourses().isEmpty())
    先排除课程列表为空或null的学生,防止后续操作触发NullPointerException。

  • 展开一对多关系:flatMap(...)
    把每个学生的课程列表转换成流,再将每门课程和对应的学生包装成SimpleEntry(键为课程ID,值为学生),flatMap会把所有这些Entry合并成一个连续的流,这样就把“一个学生对应多门课”的关系拆成了“多个(课程ID,学生)”的一对一关系。

  • 分组收集:collect(Collectors.groupingBy(...))
    用groupingBy按Entry的key(课程ID)分组,再通过mapping提取Entry的value(学生),最终收集成每个课程ID对应的学生列表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:40:58