Java 关于Iterable接口的多种用途是否有正式合同?
自Java 5以来,我们有了一种新类型,可以在foreach循环中使用:Java 关于Iterable接口的多种用途是否有正式合同?,java,iterable,Java,Iterable,自Java 5以来,我们有了一种新类型,可以在foreach循环中使用: for (Object element : iterable); 合同没有规定在处理Iterable之前是否可以多次调用其方法。也就是说,目前尚不清楚以下内容是否适用于所有的可移植性: for (Object element : iterable); for (Object element : iterable); 例如,迭代器包装实现不能使用两次: public class OneShotIterable<T&
for (Object element : iterable);
合同没有规定在处理Iterable之前是否可以多次调用其方法。也就是说,目前尚不清楚以下内容是否适用于所有的可移植性:
for (Object element : iterable);
for (Object element : iterable);
例如,迭代器
包装实现不能使用两次:
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;
}
}
public类OneShotIterable实现了Iterable{
私有最终迭代器;
公共OneShotIterable(迭代器it){
this.it=it;
}
@凌驾
公共迭代器迭代器(){
归还它;
}
}
对于大多数Iterables
,这是不相关的,因为它们实际上是重新安装的集合API类型,例如List
,Set
,它们已经为其迭代器()方法定义了良好的契约
我的问题是:我的OneShotIterable
实现是否违反了一些我忽略的契约?换句话说,Iterable
的用户会期望它是可重用的吗?如果是这样的话,Java 5专家组是否有“官方”建议如何处理这种“一次性”Iterables(例如,在第二次调用时抛出一个IllegalStateException
)并不是我问题的答案,但Apache Commons Collections在其IteratorUtils
类中解决了这个问题:
这两种方法都是可迭代
类型的工厂方法。上述区别清楚地表明,在Iterables
中包装迭代器时必须小心,我可以在标准库中找到的一个先例是接口
其Javadoc包含以下段落(强调):
虽然DirectoryStream
扩展了Iterable
,但它不是通用的Iterable
,因为它只支持单个迭代器;调用迭代器
方法以获取第二个或后续迭代器将抛出非法状态异常
对我来说,这意味着两件事:
- 上的隐含约定是,您应该能够多次迭代(甚至可以同时迭代!)
- 文档中的黑体警告加上抛出可能是处理您自己的类/接口中的不合规性的最佳方法
每次调用迭代器()时,您不能只增加OneShotIterable的一个字段,如果是gte n,则抛出一个异常吗?@LukasEder doh您将其编辑掉了吗