Java 为什么每次调用iterator()方法时,Iterable没有义务返回新的迭代器?
几天前,我遇到了一个奇怪的bug,它发生在我的map reduce任务中 最后,实现Java 为什么每次调用iterator()方法时,Iterable没有义务返回新的迭代器?,java,hadoop,iterator,Java,Hadoop,Iterator,几天前,我遇到了一个奇怪的bug,它发生在我的map reduce任务中 最后,实现Iterable接口的hadoopValueIterable类创建了一个迭代器实例,并在每次调用iterator()方法时返回它 protected class ValueIterable implements Iterable<VALUEIN> { private ValueIterator iterator = new ValueIterator(); @Override public
Iterable
接口的hadoopValueIterable
类创建了一个迭代器实例,并在每次调用iterator()
方法时返回它
protected class ValueIterable implements Iterable<VALUEIN> {
private ValueIterator iterator = new ValueIterator();
@Override
public Iterator<VALUEIN> iterator() {
return iterator;
}
}
受保护的类ValueIterable实现了Iterable{
私有ValueIterator迭代器=新的ValueIterator();
@凌驾
公共迭代器迭代器(){
返回迭代器;
}
}
这意味着,如果在ValueIterable
上迭代一次,就无法再次迭代
我决定检查一下,似乎每次都不需要Iterable
返回不同的迭代器(或者只是缺少要求?)。深入研究后,我发现答案告诉我们,使用单个迭代器违反了iterator
契约,因为它不能多次遍历集合
非法状态异常
,它会违反迭代器#hasNext()
方法契约吗Iterable.Iterator()
返回的每个Iterator
应该重复相同的序列。这只是一种习惯,因为这是预期的行为
因此,Hadoop或任何其他库都可以打破这方面的规则
java文档不清楚其确切目的是什么——让Iterable
的实现者有回旋的余地以任何他们想要的方式完成它
你应该怎么做-就像链接中提到的其他答案一样-保留一个已经迭代过的项目列表,供以后重复迭代-但请注意,这可能是在实时hadoop环境中的一个巨大的集合,因此你很可能会中断。ValueIterator具有重置方法。它有什么作用?可能是您需要的。@DenisGavrus可能需要,但在客户端map reduce代码中只有Iterable接口,将这个Iterable转换为内部hadoop类不是一个好主意。问题更多的是关于规范,这个hadoop类只是一个起点。真正的问题不是解决这个问题——我已经做了。我很担心,因为对我来说没有信号,迭代是不可能的,我只是得到了意想不到的行为。我想知道谁在这里有罪,以及如何纠正。@AdamSkywalker-我想说这个错误是hadoop文档造成的,或者是你自己没有阅读它。i、 e.要么文件不清楚,要么你没有仔细阅读。