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)
相关推荐
拓端研究室TRL1 小时前
【梯度提升专题】XGBoost、Adaboost、CatBoost预测合集:抗乳腺癌药物优化、信贷风控、比特币应用|附数据代码...
大数据
黄焖鸡能干四碗1 小时前
信息化运维方案,实施方案,开发方案,信息中心安全运维资料(软件资料word)
大数据·人工智能·软件需求·设计规范·规格说明书
编码小袁1 小时前
探索数据科学与大数据技术专业本科生的广阔就业前景
大数据
WeeJot嵌入式2 小时前
大数据治理:确保数据的可持续性和价值
大数据
zmd-zk3 小时前
kafka+zookeeper的搭建
大数据·分布式·zookeeper·中间件·kafka
激流丶3 小时前
【Kafka 实战】如何解决Kafka Topic数量过多带来的性能问题?
java·大数据·kafka·topic
测试界的酸菜鱼3 小时前
Python 大数据展示屏实例
大数据·开发语言·python
时差9533 小时前
【面试题】Hive 查询:如何查找用户连续三天登录的记录
大数据·数据库·hive·sql·面试·database
Mephisto.java3 小时前
【大数据学习 | kafka高级部分】kafka中的选举机制
大数据·学习·kafka
Mephisto.java3 小时前
【大数据学习 | kafka高级部分】kafka的优化参数整理
大数据·sql·oracle·kafka·json·database