spark:map 和 flatMap 的区别(Scala)

发布于:2025-05-11 ⋅ 阅读:(14) ⋅ 点赞:(0)

场景设定

假设有一个包含句子的 RDD:

scala

val rdd = sc.parallelize(List("Hello World", "Hi Spark"))  

目标是:将每个句子拆分成单词


1. 用 map 的效果

代码示例

scala

val resultMap = rdd.map(sentence => sentence.split(" "))
resultMap.collect()
输出结果

scala

Array[Array[String]] = Array(Array("Hello", "World"), Array("Hi", "Spark"))
发生了什么?
  • map 一对一转换:

    • 输入一个句子 "Hello World" → 输出一个单词数组 Array("Hello", "World")

    • 输入一个句子 "Hi Spark" → 输出一个单词数组 Array("Hi", "Spark")

  • 结果结构嵌套的数组(每个元素还是数组)。


2. 用 flatMap 的效果

代码示例

scala

val resultFlatMap = rdd.flatMap(sentence => sentence.split(" "))
resultFlatMap.collect()
输出结果

scala

Array[String] = Array("Hello", "World", "Hi", "Spark")
发生了什么?
  • flatMap 一对多转换:

    • 输入一个句子 "Hello World" → 拆分成两个单词 "Hello" 和 "World"

    • 输入一个句子 "Hi Spark" → 拆分成两个单词 "Hi" 和 "Spark"

  • 结果结构扁平化的数组(所有单词在一个数组中)。


核心区别总结

操作 输入 → 输出关系 结果结构 适用场景
map 1个输入 → 1个输出(类型可变) 保持嵌套结构 简单转换(如类型转换、数值计算)
flatMap 1个输入 → 多个输出(自动展平) 扁平化单层结构 拆分数据(如分词、展开嵌套结构)

图解对比

原始数据:          List("Hello World", "Hi Spark")  
                 ↓               ↓  
map 处理:      Array("Hello", "World")   Array("Hi", "Spark") → 结果:嵌套数组  
                 |         |            |        |  
flatMap 处理:  "Hello"    "World"     "Hi"     "Spark"      → 结果:扁平数组

什么时候用 map

  • 保留结构:比如将字符串转大写、对数字做运算。

    scala

    val numbers = sc.parallelize(List(1, 2, 3))
    val doubled = numbers.map(_ * 2)  // 输出:List(2, 4, 6)

什么时候用 flatMap

  • 拆分或展开数据:比如将句子拆成单词、展开嵌套集合。

    scala

    val nestedList = sc.parallelize(List(List(1, 2), List(3, 4)))
    val flattened = nestedList.flatMap(identity)  // 输出:List(1, 2, 3, 4)

高级用法

链式调用示例

scala

// 同时使用 map 和 flatMap
val sentences = sc.parallelize(List("Hello World", "Hi Spark"))

// 步骤分解:
// 1. 用 map 将句子转大写
// 2. 用 flatMap 拆分单词
val result = sentences
  .map(_.toUpperCase)
  .flatMap(_.split(" "))

result.collect()  // 输出:Array("HELLO", "WORLD", "HI", "SPARK")

一句总结

map 是变形,flatMap 是拆开压平!
需要保持结构用 map,需要展开数据用 flatMap


网站公告

今日签到

点亮在社区的每一天
去签到