为了弄明白flatMap和map的区别了,查了很多资料,始终不解其意。今天为了实现一个小需求,要求统计上季度不同商品销售数量,用spark写了个wordcount,统计完成。
但是在看到flatMap和map算子时,一时不知道用哪个,犹豫不决。最终,自己决定用数据直观验证他们两者的区别。
数据格式
10001#music#120180101#singer1
10002#music2#20180301#singer2
使用flatMap算子处理数据
lines.flatMap(_.split("#")).foreach(println)
输出结果:
10002
music2
20180301
singer2
10001
music1
20180101
singer1
返回的直接是一个RDD[String]
使用Map算子处理数据
lines.map(_.split("#")).foreach(println)
输出结果:
[Ljava.lang.String;@4e7cb15d
[Ljava.lang.String;@4b78c965
返回的是RDD[Array[String]]
继续对数据处理
lines.map(_.split("\t")).map(data=>{
(data(0),data(1),data(2),data(3))
}).foreach(println)
输出结果:
(10002,music2,20180301,singer2)
(10001,music1,20180101,singer1)
返回的是RDD[String,String,String,String]
再次对数据处理等到的结果和flatMap一致
lines.map(_.split("\t")).map(data=>{
(data(0),data(1),data(2),data(3))
}).foreach(dataf=>{
println(dataf._1)
println(dataf._2)
println(dataf._3)
println(dataf._4)
})
输出结果:
10002
music2
20180301
singer2
10001
music1
20180101
singer1
总结,通过上面可以发现,flatMap直接一步把一行数据切割成一份份输出;而map需要一系列操作才能把一行数据切割成一份份输出。flatMap把一个整体切割成单独的数据;map只是把一个整体切分开,但是还在同一行
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
object CountMusic {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setMaster("local[*]").setAppName("countmusic")
val sc = new SparkContext(conf)
val lines: RDD[String] = sc.textFile("D:\\JNBY\\20200401\\music1")
//flatMap算子操作数据
// lines.flatMap(_.split("#")).foreach(println)
//map算子操作数据
/** lines.map(_.split("#")).map(data=>{
(data(0),data(1),data(2),data(3))
}).foreach(ff=>{
println(ff._1)
println(ff._2)
println(ff._3)
println(ff._4)
})*/
//spark版wordcount
val value: RDD[(String, Int)] = lines.flatMap(_.split("#")).map((_,1)).reduceByKey(_+_)
println(value)
}
}