Scala中Iterator允许执行一次
背景
使用spark执行mapPartitionsWithIndex((index,iterator)=>{....}),在执行体中将iterator进行一次迭代后,再次根据iterator执行迭代,iterator迭代体未执行。
猜想及验证过程
猜测iterator只能执行一次迭代。
测试例子如下:
val rdd1 = sc.makeRDD(1 to 10,2)
val rdd2 = rdd1.mapPartitionsWithIndex{(index,iterator)=>{
var result = List[String]()
var sum = 0
var count = 0
while(iterator.hasNext){
sum += iterator.next()
}
while(iterator.hasNext){
count += 1
}
result.::(index + "|" + sum + "|" + count).iterator
}}
执行结果
res0: Array[String] = Array(0|15|0, 1|40|0)
通过执行结果可以看出sum执行了求和运算,count没有执行统计数量运算或未正确执行统计数量运算,推测可能的原因:1. iterator能够重复执行迭代,但是count的算术运算出现问题;2.iterator只能执行一次迭代;
对原因1的验证例子:
val rdd1 = sc.makeRDD(1 to 10,2)
val rdd2 = rdd1.mapPartitionsWithIndex{(index,iterator)=>{
var result = List[String]()
var sum = 0
var count = 0
while(iterator.hasNext){
sum += iterator.next()
count += 1
}
result.::(index + "|" + sum + "|" + count).iterator
}} 执行结果
res0: Array[String] = Array(0|15|5, 1|40|5)
如果iterator能够重复执行迭代,但是count的统计数量计算出现问题,那么将sum和count放在同一个迭代体中,执行结果会和在两个迭代体中执行结果一致。但是执行结果却是能够正常的统计出数量,证明了推测原因1不成立。
对原因2的验证例子:
为了单纯的验证是iterator执行问题,下边的例子去掉了spark相关的函数
val iterator = Iterator(1,2,3,4,5,6,7)
var sum = 0
while(iterator.hasNext){
sum += iterator.next
}
println("sum is " + sum)
val expression = if(iterator.isEmpty) "iterator is empty" else "iterator is not empty"
println(expression)
如果iterator只能执行一次迭代的话,expression的结果是【iterator is empty】,真实执行结果如下
sum is 28
iterator is empty
iterator: Iterator[Int] = empty iterator
sum: Int = 28
expression: String = iterator is empty
通过执行结果可以看出,expression的结果确实是【iterator is empty】,所以推测原因2成立。
结论
scala中iterator只能执行一次迭代,如果需要多次执行同一个迭代体,建议调用iterator.toList等方法,将迭代体转化为集合,再执行上述的验证例子就会正常。
扩展
1.iterator.min和iterator.max同样是通过迭代获得,所以对于同一个iterator的min和max只能获取一个。
2.java中Iterator类同scala的Iterator,只允许进行一次迭代,如果需要进行多次迭代,需要将iterator转化为集合类
3.C#中没有Iterator类,但是有IEnumerator,这个类可以通过IEnumerator.Reset方法来重置,迭代完进行重置就可以再次迭代,而对于java和scala的Iterator没有相似的方法;
补充
spark的mapPartitionsWithIndex中iterator尽量不要使用toList,原因:toList相当于将迭代数据进行了缓存,容易导致OutOfMemory的异常,iterator是流式的处理,处理完一条记录才会去读取下一条记录并且会丢弃已读的记录,无法重复使用;而iterator.toList会将所有的记录进行缓存,便于重复使用。
Scala中Iterator允许执行一次的更多相关文章
- shell 脚本中 while 只执行一次
实例代码 while read line ; do ssh -p20002 $line -o StrictHostKeyChecking=no xxxxxxxxx done < ip.txt w ...
- Crontab中shell每分钟执行一次HDFS文件上传不执行的解决方案
一.Crontab -e 加入输出Log */1 * * * * /qiwen_list/upload_to_hdfs.sh > /qiwen_list/mapred.log 2>& ...
- Unity中让Update中的方法执行一次
Unity中让Update中的方法执行一次 Unity中,很多时候,代码需要放在Update中时刻监测状态,一旦状态符合,又只需要代码执行一次:其实可以通过设置控制量的方式,让代码只执行一次:方法:设 ...
- express框架中如何只执行一次res响应操作
在做东西时候遇到一个可能会重复输出res.json的地方,重复输出会产生Error:Cannot set header after they are sent. Node.js不像c++里可以直接通过 ...
- pthread_once()使用(某个时间在整个程序中仅执行一次,不确定是那个线程)
在多线程环境中,有些事仅需要执行一次.通常当初始化应用程序时,可以比较容易地将其放在main函数中.但当你写一个库时,就不能在main里面初始化了,你可以用静态初始化,但使用一次初始化(pthread ...
- c++ 函数中的部分代码执行一次
编程时有时需要将一段代码中的某一块只执行一次: #include<iostream> using namespace std; int fun1(int a) { static bool ...
- selenium+python+unittest:一个类中只执行一次setUpClass和tearDownClass里面的内容(可解决重复打开浏览器和关闭浏览器,或重复登录等问题)
unittest框架是python自带的,所以直接import unittest即可,定义测试类时,父类是unittest.TestCase. 可实现执行测试前置条件.测试后置条件,对比预期结果和实际 ...
- scala中的val,var和lazy
转自:https://yerias.github.io/2020/03/19/scala/3/#3%EF%BC%9Alazy%E4%BF%AE%E9%A5%B0%E7%AC%A6%E5%8F%AF%E ...
- Scala中apply的用法
Scala中的 apply 方法有着不同的含义, 对于函数来说该方法意味着调用function本身, 以下说明摘自Programming in Scala, 3rd Edition Every fun ...
随机推荐
- 阿里云 esc 云服务器无缘无故的一次/usr/bin 目录丢失导致整个服务无法启动 # ./shutdown.sh ./shutdown.sh: line 41: dirname:command not found cannot find /catalina.sh the find /catalina.sh The file is absent or does not have execute
总结上个星期服务器环境上的一个问题,一直再忙AR.防近视的项目没时间整理.刚好忙完项目认真回顾8月30发生的一个让人奇葩的问题. 早上把项目上的一些问题优化完,快到中午吃饭的时间频繁的启动导致/usr ...
- oracle重装系统后恢复
前提:各种文件都存在 1.将原oracle文件夹app更名为app_old 2.重新安装oracle(路径,实例等最好都一样),配置监听,服务能正常启动,连接进入数据库 3.关掉oracle服务,将新 ...
- How secure FB Messenger is?
It's reported that FB Messenge is the most secure App for instant messaging service. Let's see if FB ...
- NK3C:关于svg文件使用
我们从 http://iconfont.cn/ 上下载的SVG文件由以下构成,系统中使用的时候请做适当的修改: 1.width.Height:设置为100%: 2.defs模块去掉:(如果不去掉,IE ...
- NPOI操作Excel导入DataTable中
using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using System.Data; using System.IO; using NPOI.X ...
- devexpress bandgridview使用总结(14.2)
这两天利用bandgridview做表头,希望做成如下形状 在制作过程中发现如果想实现动态表头,代码的书写顺序需要稍加注意 实例化gridband 绑定gridband至bandgridview gr ...
- 初尝 JFinal 项目(二)
这里以Roles角色表修改功能做一个例子 RolesController /** * 角色管理控制类 * @author 御手洗红豆 */public class RolesController ex ...
- matlab 按照某列以行为单位进行排序
a=[2 1 3 21 44 3] 然后按照第一列进行排序 sortrows(a,1) ans = 1 4 2 1 3 2 4 3 如要逆序,可以逆序读矩阵即可
- CListCtlr 控件的常见用法
今天第一次用CListCtrl控件,遇到不少问题,查了许多资料,现将用到的一些东西总结如下: 以下未经说明,listctrl默认view 风格为report 相关类及处理函数 MFC:CListCtr ...
- limux curl命令
linux curl命令很强大: http://blog.chinaunix.net/uid-14735472-id-3413867.html curl是一种命令行工具,作用是发出网络请求,然后得到和 ...