Next in hasNext implementationΒΆ
ID: java/iterator-hasnext-calls-next
Kind: problem
Severity: warning
Precision: medium
Tags:
- reliability
- correctness
Query suites:
- java-security-and-quality.qls
Click to see the query in the CodeQL repository
Iterator implementations with a hasNext method that calls the next method are most likely incorrect. This is because next changes the iteratorβs position to the next element and returns that element, which is unlikely to be desirable in the implementation of hasNext.
RecommendationΒΆ
Ensure that any calls to next from within hasNext are legitimate. The hasNext method should indicate whether there are further elements remaining in the iteration without changing the iteratorβs state by calling next.
ExampleΒΆ
In the following example, which outputs the contents of a string, hasNext calls next, which has the effect of changing the iteratorβs position. Given that main also calls next when it outputs an item, some items are skipped and only half the items are output.
public class NextFromIterator implements Iterator<String> {
private int position = -1;
private List<String> list = new ArrayList<String>() {{
add("alpha"); add("bravo"); add("charlie"); add("delta"); add("echo"); add("foxtrot");
}};
public boolean hasNext() {
return next() != null; // BAD: Call to 'next'
}
public String next() {
position++;
return position < list.size() ? list.get(position) : null;
}
public void remove() {
// ...
}
public static void main(String[] args) {
NextFromIterator x = new NextFromIterator();
while(x.hasNext()) {
System.out.println(x.next());
}
}
}
Instead, the implementation of hasNext should use another way of indicating whether there are further elements in the string without calling next. For example, hasNext could check the underlying array directly to see if there is an element at the next position.
ReferencesΒΆ
Java API Specification: Iterator.hasNext(), Iterator.next().