Spark 之 map 与 flatMap 的区别

map 函数

它将某个函数应用到集合中的每个元素,并产生一个结果集合。

我们可以这样对列表的元素进行平方:

scala 复制代码
scala> list1
res3: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
 
scala> list1.map(x=>x*x)
res4: List[Int] = List(0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100)

flatten 函数

将嵌套结构扁平化为一个层次的集合

scala 复制代码
scala> List(List(1, 2), List(3, 4)).flatten
res0: List[Int] = List(1, 2, 3, 4)

flatMap 函数

flatMap是map的一种扩展。在flatMap中,我们会传入一个函数,该函数对每个输入都会返回一个集合(而不是一个元素),然后,flatMap把生成的多个集合"拍扁"成为一个集合。

scala 复制代码
scala> val list3 = 10 to 20 toList
list3: List[Int] = List(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
 
scala> val list2 = 1 to 10 toList
list2: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
 
scala> val list4 = List(list2, list3)
list4: List[List[Int]] = List(List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), List(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20))
 
scala> list4.flatMap(x=>x.map(y=>y*2))
res2: List[Int] = List(2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40)

注:flatMap并不一定用于元素是序列的列表,他只需要应用的函数返回的结果是GenTraversableOnce即可(列表的父类),例如:

scala 复制代码
scala> List(1,2,3,4,5)
res0: List[Int] = List(1, 2, 3, 4, 5)
 
scala> res0.flatMap(x => 1 to x )
res1: List[Int] = List(1, 1, 2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 5)

flatMap还可以看作是flatten和map两种的结合

scala 复制代码
scala> val nestedNumbers = List(List(1, 2), List(3, 4))
nestedNumbers: List[List[Int]] = List(List(1, 2), List(3, 4))
 
scala> nestedNumbers.flatMap(x => x.map(_ * 2))
res0: List[Int] = List(2, 4, 6, 8)
 
//等价于
 
scala> nestedNumbers.map((x: List[Int]) => x.map(_ * 2)).flatten
res1: List[Int] = List(2, 4, 6, 8)

由以上代码可以看出,flatMap是map和flatten操作的结合,先进行map操作,然后再进行flatten操作;flatMap还可以去除掉空元素NONE。

map VS flatMap

map函数的用法,顾名思义,将一个函数传入map中,然后利用传入的这个函数,将集合中的每个元素处理,并将处理后的结果返回。而flatMap与map唯一不一样的地方就是传入的函数在处理完后返回值必须是List,其实这也不难理解,既然是flatMap,那除了map以外必然还有flat的操作,所以需要返回值是List才能执行flat这一步。

例子:

scala 复制代码
object collection_t1 {

  def flatMap1(): Unit = {
    val li = List(1,2,3)
    val res = li.flatMap(x => x match {
      case 3 => List('a','b')
      case _ => List(x*2)  //输出需要为 List
    })
    println(res)
  }

  def map1(): Unit = {
    val li = List(1,2,3)
    val res = li.map(x => x match {
      case 3 => List('a','b')
      case _ => x*2 // 输入不需要为 List
    })
    println(res)
  }

  def main(args: Array[String]): Unit = {
    flatMap1()
    map1()
  }
}

输出为:

scala 复制代码
List(2, 4, a, b)
List(2, 4, List(a, b))

特别的例子:

scala 复制代码
scala> val books = List("Hadoop", "Hive", "HDFS")
books: List[String] = List(Hadoop, Hive, HDFS)

scala>  books map (s => s.toList)
res3: List[List[Char]] = List(List(H, a, d, o, o, p), List(H, i, v, e), List(H, D, F, S))

scala>  books flatMap (s => s.toList)
res2: List[Char] = List(H, a, d, o, o, p, H, i, v, e, H, D, F, S)

scala> books.map(s => s.toUpperCase)
res1: List[String] = List(HADOOP, HIVE, HDFS)

// flatMap函数的输出结果必须为List,然后才进行flatten,因此,需要将s.toUpperCase生成的 String
// 转为为List,如 "HADOOP".toList 变为 List[Char] = List(H, A, D, O, O, P),进行了隐式转换
// 在进行 flatten
scala> books.flatMap(s => s.toUpperCase)
res0: List[Char] = List(H, A, D, O, O, P, H, I, V, E, H, D, F, S)
相关推荐
龙亘川2 分钟前
数智赋能物业不动产治理:亘川智城智慧物业系统实践解析
大数据·人工智能·智慧城市·开源软件·数据可视化
大大大大晴天️10 分钟前
元数据目录到数据资产运营:让好数据被看见、被复用、被持续经营
大数据·数据治理
Elastic 中国社区官方博客1 小时前
错误最多的服务运行正常:使用 ES|QL 从日志进行根因分析
大数据·运维·数据库·sql·elasticsearch·搜索引擎·全文检索
计算机毕业设计杰瑞1 小时前
【2027最新精品大数据】基于大数据的全国各地景点指数数据可视化分析,附源码_高质量项目_可视化_数据分析_毕设选题推荐_SPark_Hadoop_毕设指导
大数据·信息可视化·数据分析
计算机毕业设计杰瑞1 小时前
【2027精品大数据项目】基于大数据的全球太空探索数据分析与可视化,附源码_数据可视化_数据分析_毕设选题_SPark_Hadoop_文档指导ppt
大数据·信息可视化·数据挖掘·课程设计
计算机毕业编程指导师2 小时前
【计算机毕设推荐】基于Hadoop+Django的LLM多维度性能评估分析系统源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习 深度学习
大数据·hadoop·python·django·毕业设计·课程设计·llm性能
AC赳赳老秦2 小时前
OpenClaw 与 FineBI 联动方案:公开数据自动采集与实时业务分析看板实践
大数据·开发语言·python·php·finebi·deepseek·openclaw
计算机毕业设计杰瑞2 小时前
【2027最新原创大数据】基于大数据的无人机自主导航数据分析与可视化,附源码_数据可视化_数据分析_数据挖掘_Hadoop_spark_文档指导_毕设指导
大数据·信息可视化·数据挖掘·课程设计
卷毛迷你猪2 小时前
快速实验篇(B12)异常流量与刷单识别(方法论演示)
大数据·hive·hadoop·数据挖掘·聚类
龙亘川2 小时前
探索智慧文化服务:建设初衷、整体架构、技术支撑、发展现状与实践影响
大数据·数据库·架构