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

时间:2015-12-22 09:28:02

标签: java hadoop iterator

几天前,我遇到了一个奇怪的错误,这个错误发生在我的地图缩减任务中。

最后,事实证明,实现ValueIterable接口的hadoop Iterable类创建了一个迭代器实例,并在每次调用iterator()方法时返回它。

protected class ValueIterable implements Iterable<VALUEIN> {
  private ValueIterator iterator = new ValueIterator();
  @Override
  public Iterator<VALUEIN> iterator() {
    return iterator;
  } 
}

这意味着如果您迭代ValueIterable一次,则无法再次迭代它。

我决定检查java documentation并且似​​乎每次都不需要Iterable返回不同的迭代器(或者只是缺少要求?)。深入潜水我发现this回答说有一个迭代器违反Iterator合同,因为它不能多次遍历集合。

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

  2. 这个hadoop类告诉客户端遍历是不可能的正确方法是什么?我的意思是如果它会抛出IllegalStateException,是否会违反Iterator#hasNext()方法合同?

1 个答案:

答案 0 :(得分:2)

来自here

  

从Iterable的iterator()方法中获得的迭代器是特殊的。这些值可能并非都在内存中; Hadoop可能正在从磁盘流式传输它们。它们并非真正由Collection支持,因此允许多次迭代是非常重要的。

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

Hadoop - 或任何其他库 - 因此允许违反此规则。

java文档目前还不清楚这个目的 - 让Iterable的实现者有任何摆动的空间来做任何他们想要的事情。

你应该怎么做 - 就像链接中提到的其他答案一样 - 保留已经迭代的项目列表以供以后重复迭代 - 但要注意,这可能是一个巨大的集合。活的hadoop环境,所以你可能会破裂。