Stream.flatMap()用于将嵌套集合展平为单层流,它对每个元素应用函数生成子流并自动合并;需注意null和空集合的安全处理,还可结合map保留原始上下文信息。

在 Java 中,Stream.flatMap() 是处理嵌套集合(比如“每个班级一个学生列表”)并展平为单层流的最自然方式。它的核心作用是:对流中每个元素执行一个函数,该函数返回一个新流,然后将所有这些子流“扁平化”合并成一个总流。
理解 flatMap 的输入与输出
flatMap 接收一个 Function<t stream>></t>:
- 每个原始元素(例如一个 ClassRoom 对象)被映射为一个 Stream<student></student>;
- 所有这些学生流被自动连接(concatenated),形成一个统一的 Stream<student></student>。
这和 map 不同:map 会产出 Stream<stream>></stream>,还需额外调用 flatMap(Function.identity()) 才能展平。
基础用法:从班级列表到学生流
假设有如下结构:
// 示例数据
List
new ClassRoom("一班", List.of(new Student("张三"), new Student("李四"))),
new ClassRoom("二班", List.of(new Student("王五"), new Student("赵六"), new Student("钱七")))
);
只需一行即可合并所有学生:
Stream
.flatMap(room -> room.getStudents().stream());
之后可链式操作,如:
-
.filter(s -> s.getName().length() > 2)—— 筛选名字超两个字的学生 -
.map(Student::getName)—— 提取姓名流 -
.collect(Collectors.toList())—— 收集为列表
注意空集合与 null 安全
如果某个班级的 getStudents() 返回 null 或空列表,直接调用 .stream() 会抛出 NullPointerException 或产生无意义结果。推荐写法:
.flatMap(room -> Optional.ofNullable(room.getStudents())
.orElse(Collections.emptyList())
.stream())
或者更简洁地使用:
.flatMap(room -> room.getStudents() != null
? room.getStudents().stream()
: Stream.empty())
进阶:合并时附加班级信息
若需保留学生所属班级,可在 flatMap 内部做映射:
record StudentWithClass(String name, String className) {}
Stream
.flatMap(room -> room.getStudents().stream()
.map(s -> new StudentWithClass(s.getName(), room.getName())));
这样每个学生都携带了来源班级名,便于后续分组或标记。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











