combineByKey函数源码如下:
def combineByKey[C](
createCombiner: V => C, //当前值作为参数,可被认为初始化操作
mergeValue: (C, V) => C, //在分区中操作,把当前的元素V合并到上次结果的C中
mergeCombiners: (C, C) => C): RDD[(K, C)] = self.withScope { //把每个分区的结果进行最终的计算
combineByKeyWithClassTag(createCombiner, mergeValue, mergeCombiners)(null)
}
以下两个示例来讲解combineByKey函数:
示例1:实现wordCount
val conf = new SparkConf().setAppName("combineByKey")
conf.setMaster("local")
val sc = new SparkContext(conf)
//读取hdfs文件并创建rdd对象 hello.txt文件如下:
val rdd = sc.textFile("hdfs://master:9000/user/hadoop/spark/xxx.txt")
val result = rdd.flatMap(_.split(" ")).map((_,1)).combineByKey(x=>x,(m:Int,n:Int)=>(m+n),(a:Int,b:Int)=>(a+b)).collect
println(result.toBuffer)
执行结果如下:
(m:Int,n:Int) => (m+n)是对每个分区中元素进行的操作,(a:Int,b:Int) => a+b 得到每个分区的结果进行最后的累加。
示例2:将数组中的1的放入一个集合中,2的放到一个集合中
利用并行化方式创建rdd
val rdd2 = sc.parallelize(Array((1, "dog"), (2, "gnu"), (2, "salmon"), (2, "rubbit"), (1, "turkey"), (2, "wolf"), (2, "bear"), (2, "bee")), 3)
val result2 = rdd2.combineByKey(List(_),(m:List[String],n:String)=>m:+n,(a:List[String],b:List[String])=>a:::b).collect()
println(result2.toBuffer)
执行结果如下:
1、List(_):初始化一个List集合。
2、(m:List[String],n:String) => m:+n,其中m:List[String]是分区中的第一个元素,所以创建一个list,n为当前的元素,执行m:+n,把n元素放到m集合中。
3、(a:List[String],b:List[String]) => a:::b,每个分区的结果都是一个List,a:::b则把他们连接一起。