Spark-Operator-Map
note 1
这里只是将我学习初期笔记拿来分享,没有做太多精细的推理验证,如有错误,希望指正。
note 2
整个算子系列应用的测试数据是相同的,在本系列第一篇Spark-Operator-Map中有完整的测试数据
note 3
因为工作环境如此,我个人使用Java+Scala混合开发,请知悉
note 4
代码版本
-Spark2.2
-Scala2.11
首先放以下这个系列所用的测试数据
# sparkbasic.txt
1,a,c,b
2,w,gd,h
3,h,r,x
4,6,s,b
5,h,d,o
6,q,w,e
# sparkbasic3.txt
3,h,r,x
4,6,s,b
5,h,d,o
6,q,w,e
7,j,s,b
8,h,m,o
9,q,w,c
Map
- 源码
/**
* Return a new RDD by applying a function to all elements of this RDD.
*/
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))
}
- 入参是一个 函数
对每行执行这个函数
方法细节探究
以下测试
测试数据
1,a,c,b
2,w,gd,h
3,h,r,x
4,6,s,b
5,h,d,o
6,q,w,e
package basic
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.SparkSession
/**
*
*/
class Wrap(x : String){
val name = x;
def sayName(): Unit ={
println(x)
}
def getName(): String = {
this.x
}
}
class Transform {
}
object Transform{
val ss = SparkSession.builder().master("local").appName("basic").getOrCreate()
val sc = ss.sparkContext
sc.setLogLevel("error")
val rdd = sc.textFile("/home/missingli/IdeaProjects/SparkLearn/src/main/resources/sparkbasic.txt")
def run(): Unit ={
val list = rdd.map(r => List(new Wrap(r)))
println("sayName")
val saylist =list.map(_(0).sayName())
println("sayName + collect")
saylist.collect()
println("sayName + println")
saylist.foreach(println)
println()
println("getName + println")
list.map(_(0).getName()).foreach(println)
println("---------")
val x =rdd.map(r=>r.split(",",-1)).map(r=>(r(0),r)).sortByKey(false).saveAsTextFile("/home/missingli/IdeaProjects/SparkLearn/src/main/resources/sparkbasic2.txt")
}
def main(args: Array[String]): Unit = {
run()
}
}
控制台打印输出结果
sayName
sayName + collect
1,a,c,b
2,w,gd,h
3,h,r,x
4,6,s,b
5,h,d,o
6,q,w,e
sayName + println
1,a,c,b
()
2,w,gd,h
()
3,h,r,x
()
4,6,s,b
()
5,h,d,o
()
6,q,w,e
()
getName + println
1,a,c,b
2,w,gd,h
3,h,r,x
4,6,s,b
5,h,d,o
6,q,w,e
---------
- 这里可以看到 map的一些注意事项
- 在map中执行的函数因为惰性机制,在 collect的时候才会触发执行
- 在 sayName+collect的情况下可以看到
- map 与 foreach 是 流式执行的,每次 执行一次 sayName之后,会执行一个对应的 println
排序的 文件输出结果
(6,[Ljava.lang.String;@de8649d)
(5,[Ljava.lang.String;@5e00618e)
(4,[Ljava.lang.String;@52b91a05)
(3,[Ljava.lang.String;@70251ddc)
(2,[Ljava.lang.String;@6ee2155b)
(1,[Ljava.lang.String;@3118cff0)
总结
map的用法
- 可以用来讲 RDD中的每一行包装成一个类
- 处理结构化/半结构化数据
- 可以在其中执行 方法(函数)
- 用于对数据进行计算
map的注意实现
- 需要 行动算子 触发执行
- (map)链式操作是以一行为单位进行的,而不是对所有数据进行其中一个步骤,结束后再进行下一个步骤