Java Iterator implementation - next() and hasNext() enforcing order

I might be missing something here, but why not call hasNext() internally in your implementation?


Requiring that hasNext() be called before next() violates the iterator contract. You really should rewrite it so that next() simply throws a NoSuchElementException if there is no element to return.


I imagine you're doing something like this:

class IteratorImpl<T> implements Iterator<T> {
  private Source<T> source = ...
  private T next = null;

  public boolean hasNext() {
    if(next == null) {
      next = source.poll();
    }
    return next != null;
  }

That sounds OK to me. I can't imagine a situation where you'd want to use next without hasNext - it would be a recipe for exceptions.


EDIT:

The doc for hasNext() says:

Returns true if the iteration has more elements. (In other words, returns true if next would return an element rather than throwing an exception.)

To me, the implementation does not violate the contract. However, I would (as Fabian Steeg implies) still implement next() as:

  public T next() {
    if(!hasNext()) {
      throw new NoSuchElementException();
    }
    T ret = next;
    next = null;
    return ret;
  }

I mean, what does that check really cost you?

You must check and throw a NoSuchElementException as per the API contract. Either testing on !hasNext() or next == null will meet this criteria, I believe, but I would favour the former.

If someone is catching NoSuchElementException instead of calling hasNext(), you probably have bigger problems.