Is there any official contract for the Iterable interface with respect to multiple usage?

一个人想着一个人 提交于 2019-12-09 05:22:50

问题


Since Java 5, we have the new java.lang.Iterable type that can be used in foreach loops as such:

for (Object element : iterable);

The Iterable contract does not specify whether its iterator() method can be called more than once before disposing of the Iterable. I.e., it is not clear whether the following can be expected to work for all Iterables:

for (Object element : iterable);
for (Object element : iterable);

For instance, an Iterator wrapping implementation cannot be used twice:

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;
    }
}

For most Iterables, this is irrelevant, as they are in fact retro-fitted Collection API types such as List, Set, which already have well-defined contracts for their iterator() methods.

My question is: Is my OneShotIterable implementation violating some contract that I'm overlooking? In other words, will users of an Iterable expect it to be reusable? If so, is there an "official" recommendation by the Java 5 expert group how to deal with such "one shot" Iterables (e.g. throw an IllegalStateException on a second call)?


回答1:


One precedent that I could find in the standard library is the DirectoryStream interface.

Its Javadoc contains the following passage (emphasis theirs):

While DirectoryStream extends Iterable, it is not a general-purpose Iterable as it supports only a single Iterator; invoking the iterator method to obtain a second or subsequent iterator throws IllegalStateException.

To me, this suggests two things:

  • The implied contract on Iterable is that you're supposed to be able to iterate more than once (perhaps even concurrently!)
  • A boldface warning in the documentation coupled with throwing IllegalStateException is probably the best way to handle non-compliance in your own classes/interfaces.



回答2:


Not really an answer to my question, but Apache Commons Collections has addressed this issue in its IteratorUtils class:

  • IteratorUtils.asIterable(Iterator)
  • IteratorUtils.asMultipleUseIterable(Iterator)

Both are factory methods for the IteratorIterable type. The above distinction makes it clear that one must take care when wrapping Iterators in Iterables.



来源:https://stackoverflow.com/questions/15781739/is-there-any-official-contract-for-the-iterable-interface-with-respect-to-multip

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!