flatMap的核心作用是将流中每个元素展开为多个元素并合并成扁平化流;它与map的区别在于map是一对一转换,flatMap是一对多转换且必须返回Stream。

flatMap 的核心作用是把一个流中的每个元素“展开”成多个元素,再把这些元素合并成一个新的扁平化流。它和 map 的关键区别在于:map 一对一转换(返回单个结果),flatMap 一对多转换(返回一个 Stream,然后自动展平)。
flatMap 基本写法
flatMap 接收一个函数,该函数对每个元素返回一个 Stream,flatMap 会把所有这些 Stream 合并成一个整体流:
- 函数签名:
Stream<r> flatMap(Function<t stream>> mapper)</t></r> - 必须返回
Stream,不能直接返回集合或数组;如果返回 null,会抛NullPointerException - 常见返回方式:用
Stream.of(...)、list.stream()、Arrays.stream(...)
处理嵌套集合(最常用场景)
比如有一组用户,每个用户有多个手机号,想得到所有手机号的去重列表:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
List<User> users = Arrays.asList(
new User("张三", Arrays.asList("13800138000", "13900139000")),
new User("李四", Arrays.asList("15800158000"))
);
List<String> allPhones = users.stream()
.flatMap(u -> u.getPhones().stream()) // 每个用户 → 手机号 Stream,再自动合并
.distinct()
.collect(Collectors.toList());
拆分字符串或生成多值
把一行文本按空格切分成单词,再全部转小写并去重:
立即学习“Java免费学习笔记(深入)”;
- 注意:不能用
str.split(" ").stream()直接 map,那样会得到Stream<String[]>;必须用 flatMap 展开 - 正确写法:
List<String> lines = Arrays.asList("Hello World", "Java Stream");
List<String> words = lines.stream()
.flatMap(line -> Arrays.stream(line.split("\s+"))) // 每行 → 单词流
.map(String::toLowerCase)
.distinct()
.collect(Collectors.toList());
避免常见错误
- 误用 map + collect:比如
map(u -> u.getPhones()).collect(Collectors.toList())得到的是List<List<String>>,不是扁平结构 - 返回 null:
flatMap(u -> u.getPhones() == null ? null : u.getPhones().stream())会 NPE,应改用Optional.ofNullable(...).map(List::stream).orElseGet(Stream::empty) - 混淆 flatMap 和 forEach:flatMap 是中间操作、返回新流;forEach 是终端操作、无返回,不能链式继续

















