有关多次使用的Iterable接口是否有任何正式合同?

Luk*_*der 15 java iterable

从Java 5开始,我们有了一个java.lang.Iterable可以在foreach循环中使用的新类型:

for (Object element : iterable);
Run Code Online (Sandbox Code Playgroud)

Iterable合同没有规定是否其iterator()方法可以在可迭代的处理之前被调用一次以上.即,不清楚以下是否可以为所有人工作Iterables:

for (Object element : iterable);
for (Object element : iterable);
Run Code Online (Sandbox Code Playgroud)

例如,Iterator包装实现不能使用两次:

public class OneShotIterable<T> implements Iterable<T> {
    private final Iterator<T> it;

    public OneShotIterable(Iterator<T> it) {
        this.it = it;
    }

    @Override
    public Iterator<T> iterator() {
        return it;
    }
}
Run Code Online (Sandbox Code Playgroud)

对于大多数Iterables,这是无关紧要的,因为它们实际上是改装收集API类型,例如List,Set,这已经为自己定义明确合同iterator()的方法.

我的问题是:我的OneShotIterable实施是否违反了我忽略的一些合同?换句话说,用户是否Iterable希望它可以重复使用?如果是这样,Java 5专家组是否有"官方"建议如何处理这样的"一次性" Iterables(例如,IllegalStateException在第二次通话时抛出)?

NPE*_*NPE 16

我可以在标准库中找到的一个先例是DirectoryStream界面.

它的Javadoc包含以下段落(强调他们的):

虽然DirectoryStream扩展Iterable,但它不是一般用途,Iterable因为它只支持一个Iterator; 调用该iterator方法以获取第二个或后续的迭代器抛出IllegalStateException.

对我来说,这表明两件事:

  • 暗示合同Iterable是你应该能够多次迭代(甚至可能同时进行!)
  • 一个粗体加上投掷的文档中的警告IllegalStateException可能是处理不遵守自己的类/接口的最佳途径.