网上很多分析flatMap和Map的不同,找几个还不错的,在加上自己的理解:
参考1 https://www.jianshu.com/p/c64f278a9902
- map操作
val lineArray = Array("hello you","hello me","hello world")
val lines = sc.parallelize(lineArray, 1)
val words = lines.map(line =>{ line.split(" ") })
words.foreach {
word => println(word.mkString)
}
- flatMap操作
val lineArray = Array("hello you","hello me","hello world")
val lines = sc.parallelize(lineArray, 1)
val words = lines.flatMap(line =>{ line.split(" ") })
words.foreach {
word => println(word.mkString)
}
Map操作,size和之前并不发生改变,而flatMap操作,在Map的基础上,将所有元素都展开了,导致变换后的size > 原始 数据的size。
再看一个例子
参考2 https://www.cnblogs.com/wbh1000/p/9846401.html
import org.apache.spark.{SparkConf, SparkContext}
object MapAndFlatMap {
def main(args: Array[String]): Unit = {
val sc = new SparkContext(new SparkConf().setAppName("map_flatMap_demo").setMaster("local"))
val arrayRDD =sc.parallelize(Array("a_b","c_d","e_f"))
arrayRDD.foreach(println) //打印结果1
arrayRDD.map(string=>{
string.split("_")
}).foreach(x=>{
println(x.mkString(",")) //打印结果2
})
arrayRDD.flatMap(string=>{
string.split("_")
}).foreach(x=>{
println(x.mkString(","))//打印结果3
})
}
}
为什么打印结果3没有 ”,“
是因为 flatMap把所有元素都看作是一个Array,如Array(“a”)、Array(“b”)
所以当Array元素是1时,mkstring自然失效了。
举这个例子更能直观的感受到flatMap把所有元素都拆分,而不保留原来每行的结构。
以上两个例子都是节选自网络
其实查看map和flatMap的 官网API
可以定义输出类型[B],如果搞不懂,可以善于利用这个来解除疑惑:
val tmp: RDD[(String, String)] = res.flatMap[(String, String)](sample => {
var pairSeq = Seq[(String,String)]()
var previousItem:String = null
sample.foreach((element:String) => {
if(previousItem != null){
pairSeq = pairSeq :+ (previousItem, element)
}
previousItem = element
})
pairSeq
})
tmp.take(3).foreach { println }
println("@@@@@@@@@@@@@@@@@@@@@@@@@")
val tmp2: RDD[Seq[(String, String)]] = res.map[Seq[(String,String)]](sample => {
var pairSeq = Seq[(String,String)]()
var previousItem:String = null
sample.foreach((element:String) => {
if(previousItem != null){
pairSeq = pairSeq :+ (previousItem, element)
}
previousItem = element
})
pairSeq
})
tmp2.take(3).foreach { println }
结果展示:
原始res:RDD[Seq[String]]
WrappedArray(151, 541, 293, 296, 318, 260, 253, 223)
WrappedArray(62, 110, 589, 70, 908, 480, 266, 3, 260, 541, 924)
WrappedArray(589, 858, 904, 919, 260, 318, 924, 953, 50, 32, 541, 457, 593, 223, 490, 175, 1, 610, 788, 480, 316, 329)
tmp : RDD[(String, String)]
(151,541)
(541,293)
(293,296)
还有很多行。。。
@@@@@@@@@@@@@@@@@@@@@@@@@
tmp2:RDD[Seq[(String, String)]]
List((151,541), (541,293), (293,296), (296,318), (318,260), (260,253), (253,223))
List((62,110), (110,589), (589,70), (70,908), (908,480), (480,266), (266,3), (3,260), (260,541), (541,924))
List((589,858), (858,904), (904,919), (919,260), (260,318), (318,924), (924,953), (953,50), (50,32), (32,541), (541,457), (457,593), (593,223), (223,490), (490,175), (175,1), (1,610), (610,788), (788,480), (480,316), (316,329))
正如我上文所说,map把每行的结果转换之后,返回结果之和,且size和原始res是一致的。
而flatMap则是将map结果每行都拆开,单独作为一行,生成结果size > 原始res 的size。