為了弄明白flatMap和map的區(qū)別了芝加,查了很多資料,始終不解其意射窒。今天為了實(shí)現(xiàn)一個(gè)小需求藏杖,要求統(tǒng)計(jì)上季度不同商品銷售數(shù)量,用spark寫了個(gè)wordcount脉顿,統(tǒng)計(jì)完成蝌麸。
但是在看到flatMap和map算子時(shí),一時(shí)不知道用哪個(gè)艾疟,猶豫不決来吩。最終,自己決定用數(shù)據(jù)直觀驗(yàn)證他們兩者的區(qū)別蔽莱。
數(shù)據(jù)格式
10001#music#120180101#singer1
10002#music2#20180301#singer2
使用flatMap算子處理數(shù)據(jù)
lines.flatMap(_.split("#")).foreach(println)
輸出結(jié)果:
10002
music2
20180301
singer2
10001
music1
20180101
singer1
返回的直接是一個(gè)RDD[String]
使用Map算子處理數(shù)據(jù)
lines.map(_.split("#")).foreach(println)
輸出結(jié)果:
[Ljava.lang.String;@4e7cb15d
[Ljava.lang.String;@4b78c965
返回的是RDD[Array[String]]
繼續(xù)對(duì)數(shù)據(jù)處理
lines.map(_.split("\t")).map(data=>{
(data(0),data(1),data(2),data(3))
}).foreach(println)
輸出結(jié)果:
(10002,music2,20180301,singer2)
(10001,music1,20180101,singer1)
返回的是RDD[String,String,String,String]
再次對(duì)數(shù)據(jù)處理等到的結(jié)果和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)
})
輸出結(jié)果:
10002
music2
20180301
singer2
10001
music1
20180101
singer1
總結(jié)弟疆,通過上面可以發(fā)現(xiàn),flatMap直接一步把一行數(shù)據(jù)切割成一份份輸出碾褂;而map需要一系列操作才能把一行數(shù)據(jù)切割成一份份輸出兽间。flatMap把一個(gè)整體切割成單獨(dú)的數(shù)據(jù);map只是把一個(gè)整體切分開正塌,但是還在同一行
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算子操作數(shù)據(jù)
// lines.flatMap(_.split("#")).foreach(println)
//map算子操作數(shù)據(jù)
/** 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)
}
}