Spark-map和flatmap的区别

这是一个常见的面试题,可是到现在我只会用map,并不会用flatmap,这二者到底有什么区别呢?

觉得类似问题首先要查阅他们二者API的异同,这也是以后学习的一种方法,首先看map的API:

def map[U: ClassTag](f: T => U): RDD[U] = withScope {
    val cleanF = sc.clean(f)
    new MapPartitionsRDD[U, T](this, (context, pid, iter) => iter.map(cleanF))
  }

我们之前有解析过map方法,调用 map 时,会传入匿名函数 f: T => U,该函数将一个类型 T 实例转换成一个类型 U 的实例。我们可以看到在map方法中,它就是让一个元素映射成为另一个元素,这里的元素可以是一个int,String,也可以是一个map,如(String,Int),总之,它的功能就是对每个rdd进行1对1的操作,输入的是N个元素,输出的也是N个元素。

再来看flatmap:

def flatMap[U: ClassTag](f: T => TraversableOnce[U]): RDD[U] = withScope {
    val cleanF = sc.clean(f)
    new MapPartitionsRDD[U, T](this, (context, pid, iter) => iter.flatMap(cleanF))
  }

和map相似,传入的也是一个匿名函数,但是是将T转化为TraversableOnce[U],那么TraversableOnce[U]是什么呢?经过查找相关资料,这个东西是可被遍历的,也就是说这玩意就是一个seq。也就是说flatmap先将这些元素形成一个集合,再对集合里的每个元素遍历使用一个转化的方法,将集合中的每个元素映射为另一个元素,最终还是一个集合。那么我们要想得到这个集合里的元素怎么办呢?遍历出来即可。

在知乎上找到这么一个形象的说法:

map会将每一条输入映射为一个新对象。{苹果,梨子}.map(去皮) = {去皮苹果,去皮梨子},其中:“去皮”函数的类型为:A => B 。

flatMap包含两个操作:会将每一个输入对象输入映射为一个新集合,然后把这些新集合连成一个大集合。 {苹果,梨子}.flatMap(切碎) = {苹果碎片1,苹果碎片2,梨子碎片1,梨子碎片2} 其中:“切碎”函数的类型为:A => List<B>。
是不是很形象呢?

补充:foreach方法

  def foreach[U](f: A => U): Unit =
    iterator.foreach(f)
Scala中的集合对象都有foreach和map两个方法。两个方法的共同点在于:都是用于遍历集合对象,并对每一项执行指定的方法。而两者的差异在于:foreach无返回值(准确说返回void),map返回集合对象。见如下代码及运行结果:b.getClass 得到的是void, 而c.getClass得到的是colletion 。再看代码的第9-11行,foreach和map的运行结果一致。结论就是:foreach 无法代替map. 而map方法却可以代替foreach



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值