stream流中flatmap和map区别

2025-03-18T11:28:00

Java Stream 流中一个非常经典、容易混淆的知识点,理解它对你以后函数式编程和链式处理非常有帮助。


✅ 核心区别:

方法返回结果类型作用
map一对一映射(元素 → 元素)把流中的每个元素映射成另外一个对象,结果还是一个元素流
flatMap一对多扁平化映射(元素 → 流 → 合并成一个流)把流中的每个元素映射成一个流(或集合),然后把所有小流拍平成一个大流

✅ 举例理解

1️⃣ map 示例

List<String> words = List.of("hello", "world");

List<Integer> lengths = words.stream()
    .map(String::length) 
    .collect(Collectors.toList());

System.out.println(lengths);  // [5, 5]
  • 每个元素(String) → 映射成一个长度(Integer),所以是一对一。

2️⃣ flatMap 示例

List<String> words = List.of("hello", "world");

List<String> letters = words.stream()
    .flatMap(word -> Arrays.stream(word.split("")))  
    .collect(Collectors.toList());

System.out.println(letters);  
// [h, e, l, l, o, w, o, r, l, d]
  • 每个元素(单词)→ 映射成一个「字符数组流」,然后把所有字符流合并,形成一个大流。
  • 如果你用 map 而不是 flatMap,结果会是 Stream<Stream<String>>,嵌套两层,不方便处理。

✅ 图示理解(你可以在脑子里画一下)

  • map
[hello]   -> [hello length = 5]
[world]   -> [world length = 5]
结果: [5, 5]
  • flatMap
[hello]   -> [h, e, l, l, o]
[world]   -> [w, o, r, l, d]
结果: [h, e, l, l, o, w, o, r, l, d]

用一句话+小例子帮助记忆:

✅ 一句话记忆

  • map:一个元素变成一个元素。
  • flatMap:一个元素变成多个元素(拍平)。

✅ 简单例子

List<String> list = List.of("a,b", "c,d");

// 用 map:得到的还是两个字符串(中间逗号没拆)
list.stream()
    .map(s -> s.split(","))
    // 变成 Stream<String[]>,结果是嵌套数组
    .forEach(arr -> System.out.println(Arrays.toString(arr)));
// 输出: [a, b]  [c, d]

// 用 flatMap:每个元素拆成多个元素,拍平
list.stream()
    .flatMap(s -> Arrays.stream(s.split(",")))
    .forEach(System.out::println);
// 输出:a b c d

✅ 口诀

  • map 是「变形」
  • flatMap 是「拆开」



✅ 前瞻性角度

  • 如果将来处理复杂对象集合flatMap 是处理「嵌套集合」和「拆平」的利器。
  • 比如 List<List<Integer>> 想要变成 List<Integer>,一行 flatMap 解决。
  • 在 WebFlux、Reactor 等响应式框架中,flatMap 的思维同样重要(流中的流解构)。

当前页面是本站的「Baidu MIP」版。发表评论请点击:完整版 »