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)
相关推荐
WTT00112 小时前
2024楚慧杯WP
大数据·运维·网络·安全·web安全·ctf
云云3216 小时前
怎么通过亚矩阵云手机实现营销?
大数据·服务器·安全·智能手机·矩阵
新加坡内哥谈技术6 小时前
苏黎世联邦理工学院与加州大学伯克利分校推出MaxInfoRL:平衡内在与外在探索的全新强化学习框架
大数据·人工智能·语言模型
Data-Miner7 小时前
经典案例PPT | 大型水果连锁集团新零售数字化建设方案
大数据·big data
lovelin+v175030409667 小时前
安全性升级:API接口在零信任架构下的安全防护策略
大数据·数据库·人工智能·爬虫·数据分析
道一云黑板报8 小时前
Flink集群批作业实践:七析BI批作业执行
大数据·分布式·数据分析·flink·kubernetes
节点。csn8 小时前
flink集群搭建 详细教程
大数据·服务器·flink
数据爬坡ing8 小时前
小白考研历程:跌跌撞撞,起起伏伏,五个月备战历程!!!
大数据·笔记·考研·数据分析
云云3219 小时前
云手机方案全解析
大数据·服务器·安全·智能手机·矩阵