I think it's perfectly reasonable to have an iterator which,
internally, may fetch the next element when hasNext() is called. However, as far as what it looks like from outside the API (i.e. to people using it), you need to make sure it
looks like hasNext() does not have any side effects, and only next() advances the pointer. This means you'll have to remember if hasNext() is called multiple times without next() - you don't keep fetching new elements; you have to wait until next() is called to move on. Furthermore even if hasNext() has
never been called, next() should be able to return the next element if there is one (and throw NoSuchElementException otherwise). Consider this code:
Now this is a pretty silly way to use an iterator, but it shows off the special cases you need to consider. I think the API
does make it clear enough that next() should return the next element, period (even if hasNext() is not called). And the ability to actually advance though the data structure is stipulated under next(), not hasNext(). It's not stated as clearly as we might like, but I think it's clear enough.
The above code was extremely contrived, of course. But I
have seen, and even occasionally written, code that calls hasNext() more than once on a given iteration. For exampls, here's a method to convert a collection of objects to a
string in which the objects are separated by a delimiter (e.g. a comma):
There are other ways this could be done - but the point is, this is a perfectly reasonable thing to do, and I would expect to get each element in the collection exactly once. Even though hasNext() is being called twice on each iteration.
Hope that helps...
[ January 10, 2006: Message edited by: Jim Yingst ]