flatmap是java stream api中用于“一对多”映射并自动扁平化结果的核心方法,它接收返回stream的函数,将每个元素映射为子流后合并为单一扁平流,适用于展开嵌套集合、处理optional及字符串分词等场景。

flatMap 是 Java Stream API 中用于“一对多”映射并自动扁平化结果的核心方法。它接收一个函数,该函数对每个元素返回一个 Stream,然后将所有子流合并成一个单一的、不嵌套的流。
核心用法:传入 Function>,自动合并子流
与 map 返回单个对象不同,flatMap 的映射函数必须返回一个 Stream;系统会把每个元素产生的流“打散”,再把所有元素依次拼接,最终得到一个扁平流。
- 输入:一个流(如
Stream<list>></list>) - 映射函数:对每个
List<string></string>调用list.stream(),生成一个Stream<string></string> - flatMap 自动把多个
Stream<string></string>合并为一个Stream<string></string>
常见场景:展开 List>、处理 Optional、分割字符串
以下是最典型的三种用法:
-
展开嵌套集合:
List- > nested = Arrays.asList(Arrays.asList(1,2), Arrays.asList(3), Arrays.asList(4,5,6));
Streamflat = nested.stream().flatMap(list -> list.stream());
// 结果:[1, 2, 3, 4, 5, 6] -
安全展开可能为空的值(配合 Optional):
List> optionals = Arrays.asList(Optional.of("a"), Optional.empty(), Optional.of("b"));
Streampresent = optionals.stream().flatMap(opt -> opt.stream());
// empty 的 Optional.stream() 返回空流,自动跳过,结果:["a", "b"] -
按分隔符切分并展平:
Listsentences = Arrays.asList("hello world", "java stream");
Streamwords = sentences.stream().flatMap(s -> Arrays.stream(s.split("\s+")));
// 结果:["hello", "world", "java", "stream"]
注意:flatMap 中的 Stream 必须是新创建的,不能复用
如果映射函数返回的是同一个已关闭或已遍历过的流,会抛出 IllegalStateException。每次调用都应返回一个**新鲜的、未使用的流**。
- ✅ 正确:
s -> Arrays.stream(s.split(" "))(每次新建流) - ❌ 错误:
Stream<string> cached = ...; s -> cached</string>(复用已消费流)
对比 map + flatMap:为什么不能只用 map?
如果用 map 处理嵌套集合,结果是 Stream<stream>></stream> —— 仍是嵌套结构,无法直接 forEach 或 collect。
-
map(list -> list.stream())→Stream<stream>></stream>(需再调用flatMap(Function.identity())才能扁平) -
flatMap(list -> list.stream())→ 直接得到Stream<string></string>
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











