Java 为什么每次调用iterator()方法时,Iterable没有义务返回新的迭代器?

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

几天前,我遇到了一个奇怪的bug,它发生在我的map reduce任务中

最后,实现
Iterable
接口的hadoop
ValueIterable
类创建了一个迭代器实例,并在每次调用
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
契约,因为它不能多次遍历集合

  • 这里谁是对的?Iterable是否应该返回新的迭代器?为什么java文档不清楚

  • 这个hadoop类告诉客户机遍历是不可能的,正确的方法是什么?我的意思是,如果它将抛出
    非法状态异常
    ,它会违反
    迭代器#hasNext()
    方法契约吗

  • 发件人:

    从Iterable的Iterator()方法接收的迭代器是特殊的。这些值可能不都在内存中;Hadoop可能正在从磁盘流式传输它们。它们并不是真正由一个集合支持的,所以允许多次迭代是非常重要的

    没有实际定义的契约规定,
    Iterable.Iterator()
    返回的每个
    Iterator
    应该重复相同的序列。这只是一种习惯,因为这是预期的行为

    因此,Hadoop或任何其他库都可以打破这方面的规则

    java文档不清楚其确切目的是什么——让
    Iterable
    的实现者有回旋的余地以任何他们想要的方式完成它


    你应该怎么做-就像链接中提到的其他答案一样-保留一个已经迭代过的项目列表,供以后重复迭代-但请注意,这可能是在实时hadoop环境中的一个巨大的集合,因此你很可能会中断。

    ValueIterator具有重置方法。它有什么作用?可能是您需要的。@DenisGavrus可能需要,但在客户端map reduce代码中只有Iterable接口,将这个Iterable转换为内部hadoop类不是一个好主意。问题更多的是关于规范,这个hadoop类只是一个起点。真正的问题不是解决这个问题——我已经做了。我很担心,因为对我来说没有信号,迭代是不可能的,我只是得到了意想不到的行为。我想知道谁在这里有罪,以及如何纠正。@AdamSkywalker-我想说这个错误是hadoop文档造成的,或者是你自己没有阅读它。i、 e.要么文件不清楚,要么你没有仔细阅读。