Java has had a standard interface for implementing iterators since its early days, and since Java 5, the "foreach" construction makes it easy to loop over objects that provide the <code>java.lang.Iterable</code> interface. (The [[Java collections framework]] and other collections frameworks, typically provide iterators for all collections.)
However, [[Java (programming language)|Java]] does not have generators built into the language. This means that creating iterators is often much trickier than in languages with built-in generators, especially when the generation logic is complex. Because all state must be saved and restored every time an item is to be yielded from an iterator, it is not possible to store state in local variables or use built-in looping routines, as when generators are available; instead, all of this must be manually simulated, using object fields to hold local state and loop counters.
Even simple iterators built this way tend to be significantly bulkier than those using generators, with a lot of [[boilerplate code]].
The original example above could be written in '''Java 5''' as:
<syntaxhighlight lang="java"> ▼
// Iterator implemented as anonymous class. This uses generics but doesn't need to.
for (int i: new Iterable<Integer>() {
@Override
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
int counter = 1;
@Override
public boolean hasNext() {
return counter <= 100;
}
@Override
public Integer next() {
return counter++;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}) {
System.out.println(i);
}
An infinite Fibonacci sequence could also be written in '''Java 5''' as an Iterator:
<syntaxhighlight lang="java">
Iterable<Integer> fibo = new Iterable<Integer>() {
@Override
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
int a = 1, b = 2;
@Override
public boolean hasNext() {
return true;
}
@Override
public Integer next() {
int temp = a;
a = b;
b = a + temp;
return temp;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
// this could then be used as...
for (int f: fibo) {
System.out.println("next Fibonacci number is " + f);
if (someCondition(f)) break;
}
</syntaxhighlight>
Also an infinite Fibonacci sequence could also be written using '''Java 8''' or higher Stream interface:
<syntaxhighlight lang="java">
Iterable<Integer> myIterable = Stream
</syntaxhighlight>
Or get an Iterator from the '''Java 8''' or higher super-interface BaseStream of Stream interface.
<syntaxhighlight lang="java">
// Save the iterator of a stream that generates fib sequence
System.out.println(myGenerator.next());
}
/* Output:
▲<syntaxhighlight lang=" javaconsole">
1
1
21
34
55 */
</syntaxhighlight>
|