84 lines
2.0 KiB
Plaintext
84 lines
2.0 KiB
Plaintext
== Why is this an issue?
|
|
|
|
Calling `Iterator.hasNext()` is not supposed to have any side effects and hence should not change the iterator's state. `Iterator.next()` advances the iterator by one item. So calling it inside `Iterator.hasNext()` breaks the `hasNext()` contract and will lead to unexpected behavior in production.
|
|
|
|
== How to fix it
|
|
|
|
How to fix this issue strongly depends on the specific implementation of the iterator. Make sure that the logic of the `hasNext()` implementation does not change the state of the iterator or any underlying data sources. Instead, it should merely return state information.
|
|
|
|
== Code examples
|
|
|
|
=== Noncompliant code example
|
|
|
|
[source,java,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
class MyIterator implements Iterator<Integer> {
|
|
|
|
private Queue<Integer> elements;
|
|
|
|
...
|
|
|
|
@Override
|
|
public boolean hasNext() {
|
|
try {
|
|
next(); // Noncompliant, next() is called from hasNext()
|
|
return true;
|
|
} catch (NoSuchElementException e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Integer next() {
|
|
return elements.remove();
|
|
}
|
|
}
|
|
----
|
|
|
|
=== Compliant solution
|
|
|
|
[source,java,diff-id=1,diff-type=compliant]
|
|
----
|
|
class MyIterator implements Iterator<Integer> {
|
|
|
|
private Queue<Integer> elements;
|
|
|
|
...
|
|
|
|
@Override
|
|
public boolean hasNext() {
|
|
return !elements.isEmpty(); // Compliant, no call to next()
|
|
}
|
|
|
|
@Override
|
|
public Integer next() {
|
|
return elements.remove();
|
|
}
|
|
}
|
|
----
|
|
|
|
== Resources
|
|
* https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Iterator.html[Interface Iterator<E> - Java® Platform SE 11 API Specification]
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
|
|
'''
|
|
== Implementation Specification
|
|
(visible only on this page)
|
|
|
|
=== Message
|
|
|
|
Refactor the implementation of this "Iterator.hasNext()" method to not call "Iterator.next()".
|
|
|
|
|
|
'''
|
|
== Comments And Links
|
|
(visible only on this page)
|
|
|
|
=== on 21 Nov 2024, 16:48:00 Alban Auzeill wrote:
|
|
[test-code-support-investigation-for-java] Decision for scope: Main -> All.
|
|
|
|
=== is duplicated by: S2113
|
|
|
|
endif::env-github,rspecator-view[]
|