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 |
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++];
}
}