There are two classes in the Java standard library that deal with iterations: Iterable<T> and Iterator<T>. An
Iterable<T> represents a data structure that can be the target of the "for-each loop" statement, and an
Iterator<T> represents the state of an ongoing traversal. An Iterable<T> is generally expected to support
multiple traversals.
An Iterator<T> that also implements Iterable<t> by returning itself as its iterator() will not
support multiple traversals since its state will be carried over.
This rule raises an issue when the iterator() method of a class implementing both Iterable<T> and
Iterator<t> returns this.
class FooIterator implements Iterator<Foo>, Iterable<Foo> {
private Foo[] seq;
private int idx = 0;
public boolean hasNext() {
return idx < seq.length;
}
public Foo next() {
return seq[idx++];
}
public Iterator<Foo> iterator() {
return this; // Noncompliant
}
// ...
}
class FooSequence implements Iterable<Foo> {
private Foo[] seq;
public Iterator<Foo> iterator() {
return new Iterator<Foo>() {
private int idx = 0;
public boolean hasNext() {
return idx < seq.length;
}
public Foo next() {
return seq[idx++];
}
};
}
// ...
}