liveBook · Manning

Iterator.hasNext

As explained in 100 Java Mistakes and How to Avoid Them

Iterator.hasNext is the Java Iterator method that reports whether another element is available without advancing the iteration.

Iterator.hasNext reports whether another element is available, but a custom implementation must not assume it is called only once before next. Enhanced for loops follow that narrow pattern, which can hide an incorrect iterator contract. section 8.13

The stateful hasNext mistake

An iterator that increments its cursor inside hasNext may appear correct in a for-each loop, yet repeated hasNext calls skip elements and next called first returns invalid state. Collections.min and Collections.max can call next before hasNext, including on an empty collection, where next must throw NoSuchElementException. section 8.13

Avoid the failure by following these implementation rules:

  • Make repeated hasNext calls stable; cache a prefetched value when reading from a BufferedReader. section 8.13
  • Validate availability in next, return the current element, advance afterward, and throw NoSuchElementException when exhausted. section 8.13
  • Prefer IntStream.range(...).iterator() or reader.lines().iterator() when those APIs express the intended iteration. section 8.13
public Iterator<Integer> iterator() {
  return new Iterator<>() {
    int cur = 0;

    public boolean hasNext() {
      return cur < max;
    }

    public Integer next() {
      if (!hasNext()) {
        throw new NoSuchElementException();
      }
      return cur++;
    }
  };
}

Use the corrected implementation to inspect stable hasNext behavior, validation in next, cursor advancement, and exhaustion handling. section 8.13

How 100 Java Mistakes and How to Avoid Them covers it

How deep it goes
Explains call ordering, hidden state changes, caching, exhaustion, and stream alternatives, but does not discuss static analysis.
Examples
Uses range iterators, enhanced for loops, collection extrema, BufferedReader, IntStream.range, and reader.lines.
What it assumes
Assumes familiarity with Java iterators, collections, enhanced for statements, and exceptions.
What you can do after
Build it from scratch as a contract-compliant iterator or replace custom traversal with stream-based iterators.
How it connects
Connects Iterator.hasNext with Iterator.next, Iterable, enhanced for statements, Collections.min, Collections.max, and NoSuchElementException.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 Java Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.