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 ...
随机推荐
- C# 访问MongoDB 通用方法类
using MongoDB.Driver; using System; namespace MongoDBDemo { public class MongoDb { public MongoDb(st ...
- Java笔记(一)
Java语言特征 Java之父:詹姆斯,格斯林 跨平台:一次编译,到处运行write once,run everywhere! Java是一种面向对象的编程语言(OOP)面向对象(OO -- Orie ...
- Flex使用Blazeds与Java交互及自定义对象转换详解-DATAGRID读取ORACLE数据
http://www.cnblogs.com/RocD-DuPeng/articles/1751040.html 一.建立Flex与Java交互的工程. 本文中讲到的交互是利用Blazeds的,因为这 ...
- python迭代器,生成器,装饰器,context模块
迭代器iteration 是访问集合元素的一种方式,只能往前不能往后迭代器的特点:1,访问者不需要关注迭代器内部结构,只需通过next()不断取下一个内容2,访问不能回退3,循环较大数据集合时,省内存 ...
- etcd api 接口
etcd api接口 基本操作api: https://github.com/coreos/etcd/blob/6acb3d67fbe131b3b2d5d010e00ec80182be4628/Doc ...
- mybatis读取配置文件报错:Could not find resource configuration.xml
今天用idea编译mybatis的java项目时,一直报错,找不到config.xml 查看class文件夹,确实没有xml文件 也就是说,xml文件没在编译范围内 在pom.xml中,把xml文件加 ...
- .net MVC 中枚举类型Enum 转化成 下拉列表的数据源
第一次写技术博文,记录下工作中遇到的问题,给自己的知识做个备份,也希望能帮助到其他的同学 最近接手了公司的一个新的项目.有个页面涉及相关设计. 分享一个经常用到的吧. 方法一: 直入主题吧 我们的目的 ...
- js中function参数默认值
--在dreamweaver做网站时,函数定义是在一个*.js文件中,其中定义了一个func,有四个参数,function func(string1,url,flag,icon),然后在另一个asp中 ...
- 自动备份SQL数据库 并删除指定日期之前的备份文件
/// <summary> /// 数据备份 /// </summary> /// public bool DataBackup(st ...
- 刷CM7固件 乐padA1-07专用固件
-------------------------------------------------------------------------------- 前几天在版 ...