I am writing an iterator that iterates over a list of lists by delegating to the "current" lists own iterator. (No I'm not, but this is a simple example). Now, when I reach the end of one list, I need to update the delegate to point to the next lists' iterator. Can I do this in "hasNext"? Or is it better to implement in "next" prior to returning to the caller? I feel "hasNext" should better be side effect free. What's your opinion on this?
2 に答える
It would be OK for hasNext
to have side effects as long as they are not perceptible from the outside. Above all, it must be idempotent. It is in fact often the case that hasNext
can't know whether there is a next without fetching it, and, even if it could "unfetch", it is OK to cache.
Guava's Iterators.concat
does that. From the javadocs, it:
public static <T> Iterator<T> concat(Iterator<? extends Iterator<? extends T>> inputs)
Combines multiple iterators into a single iterator. The returned iterator iterates across the elements of each iterator in {@code inputs}. The input iterators are not polled until necessary.
If you look at the source code you will see that the hasNext
method changes the current
iterator to the next iterator i.e. it is not free of side effects, so this approach is ok.