1. map
1)函数签名
def map[U: ClassTag](f: T => U): RDD[U]
2)功能描述
函数f可以接收一个参数。当某个RDD执行map方法时,会遍历该RDD中的每一个数据项,并依次应用f函数,从而产生一个新的RDD。即,这个新RDD中的每一个元素都是原来RDD中每一个元素依次应用f函数而得到的。
3)简单案例
sc.makeRDD(1 to 4,2).map(_*2).foreach(println)
2.mapPartitions
1)函数签名
def mapPartitions[U: ClassTag](
f: Iterator[T] => Iterator[U],
preservesPartitioning: Boolean = false): RDD[U]
2)功能描述
函数f接收的是每个分区的数据归集到一起的集合列表,返回结果仍然是一个集合列表。
对每个分区中的数据执行map操作,这里的map是指对数据进行处理,不限于map,可以进行filter.take等对列表的各种操作。
其实分两步,第一步spark会将每个分区的数据归集到一个集合列表中,第二步,对每个集合列表进行操作,这就存在一个问题,如果数据量比较大,很可能发生OOM异常,所以生产环境一定要结合实际情况使用。
3)简单案例
sc.makeRDD(1 to 4,2).mapPartitions(iter =>{iter.take(1)}).foreach(println)
sc.makeRDD(1 to 4,2).mapPartitions(iter =>{iter.filter(_*2==0)}).foreach(println)
sc.makeRDD(1 to 4,2).mapPartitions(iter =>{iter.map((_,1))}).foreach(println)
3. mapPartitionsWithIndex
1)函数签名
def mapPartitionsWithIndex[U: ClassTag](
f: (Int, Iterator[T]) => Iterator[U],
preservesPartitioning: Boolean = false): RDD[U]
2)功能描述
函数f接收分区号和每个分区的数据归集列表,返回结果为集合列表。
类似于mapPartitions,比mapPartitions多一个整数参数表示分区号,在计算时可以数据伴随着分区号。
其实分两步,第一步spark会将每个分区的数据归集到一个集合列表中,并将分区号和列表进行绑定,第二步,对分区号和每个分区数据的集合列表进行操作。
3)简单案例
sc.makeRDD(1 to 4).mapPartitionsWithIndex{
case (index,datas) =>{
datas.map((index,_))
}}.foreach(println)
sc.makeRDD(1 to 4).mapPartitionsWithIndex{
case (index,datas) =>{
datas.map(x =>(index,(x,1)))
}
}.foreach(println)
4. flatmap
1)函数签名:
def flatMap[U: ClassTag](f: T => TraversableOnce[U]): RDD[U]
2)功能描述:
函数f接收一个对象,返回结果为一个可迭代对象。
将RDD中的每一个元素通过应用f函数依次转换为新的元素,并封装到RDD中。
其实flatmap操作也分两步,第一步将每个元素压平,即拆分成每一个元素,也可以将一个单元素转换成集合元素,然后放入到一个集合列表list中,第二个可迭代元素压平后,再放入到list中,依次类推,所有元素压平后加入到集合list中,最终list就是最终结果。
3)简单案例
sc.makeRDD(List(1,2,3,4)).flatMap(x => List(x*2)).foreach(println)
//本来每个元素就是可以迭代的List,直接将List对象转换成iterator
sc.makeRDD(List(List(1,2,3),List(4,5,6))).flatMap(_.iterator).foreach(println)
//本来每个元素就是可迭代类型List,直接返回即可
sc.makeRDD(List(List(1,2,3),List(4,5,6))).flatMap(list => list).foreach(println)
//为避免list的疑惑性,也可这么写
sc.makeRDD(List(List(1,2,3),List(4,5,6))).flatMap(x => x).foreach(println)
//String字符串其实内部存储是数组
sc.makeRDD(List("a b c d")).flatMap(_.split(" ")).foreach(println)
//元素中存在非可遍历类型元素
val dataRDD = sc.makeRDD(List(List(1,2),3,List(4,5)))
dataRDD.flatMap {
case x: List[Int] => x.iterator
case x: Int => List(x)
}.map(_*2).foreach(println)