对比如下两段代码,其中第一段代码直接调用flatMap 方法,其输出就是先输出所有原始值 然后在在打印+1 操作的值
而第二段代码是通过iterator然后在调用flatMap 方法可以看到结果是交替输出每次计算好一个值然后输出然后在计算在输出
因此可以得到scala iternator是懒执行的不会直接计算结果,这在spark 中也是很有用的 ,比如我们在使用mappartition方法时
需要返回一个iterator常规做法我们可能声明一个集合然后计算中间结果放入集合通过集合返回迭代器,但是这种方式会占用
过多内存,这时我们就可以通过自定义迭代器方式来解决这个问题。
scala 中迭代器:
def main(args: Array[String]): Unit = {
val a = Seq(1, 2, 3, 4)
val b = a.flatMap { x =>
println("---------" + x)
Seq(x + 1)
}
b.foreach(println(_))
}
输出:
---------1
---------2
---------3
---------4
2
3
4
5
def main(args: Array[String]): Unit = {
val a = Seq(1, 2, 3, 4)
val b = a.iterator.flatMap { x =>
println("---------" + x)
Seq(x + 1)
}
b.foreach(println(_))
}
输出:
---------1
2
---------2
3
---------3
4
---------4
5
spark中mappartition:
常规用法:
dataRdd.mappartition{
val list=ListBuffer…
list.append(xxxx)
list.iterator
}
自定义迭代器方式:
dataRdd.mappartition(new MyIterator())
具体操作封装在MyIterator中
class MyIterator(it: Iterator[Row], cols: String, schemaName: Seq[String]) extends Iterator[util.ArrayList[SqlRow]]{
override def hasNext: Boolean = {
//这里直接调用传入的iterator即可
it.hasNext
}
//这里调用原始迭代器next方法获取当前值 并返回当前行计算结果
override def next(): util.ArrayList[SqlRow] = {
val curRow = it.next
curRow
}
}