Iterator next() in hasNext()

ID

java.iterator_next_in_hasnext

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Java

Tags

CWE:834, best-practice, reliability

Description

Reports Iterator.hasNext() implementations that call next() in their body.

Rationale

The hasNext() method must be a pure predicate: it checks whether more elements are available without advancing the iterator. Calling next() inside hasNext() consumes an element during the check, causing skipped elements, off-by-one errors, or infinite loops:

class BadIterator implements Iterator<String> {
    public boolean hasNext() {
        try {
            next();        // Advances the iterator during a check
            return true;
        } catch (NoSuchElementException e) {
            return false;
        }
    }
}

Remediation

Implement hasNext() by checking internal state without calling next():

class GoodIterator implements Iterator<String> {
    private int index = 0;
    private String[] data;

    public boolean hasNext() {
        return index < data.length;  // Pure predicate
    }

    public String next() {
        if (!hasNext()) throw new NoSuchElementException();
        return data[index++];
    }
}