从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可能是处理不遵守自己的类/接口的最佳途径.