Foreach z Javy pod maską używa dokładnie Iteratora. Dokładniej to foreach przyjmuje jako parametr dowolne Iterable, a Iterable ma metodę iterator() która zwraca świeży Iterator.
ArrayList implementuje Iterable i dlatego możesz tego użyć w foreachu.
Foreach działa też dla tablic, chociaż nie implementują one interfejsu Iterable - ale to raczej szczegół w kontekście problemu z pierwszego posta.
Przykład implementacji:
import java.util.Iterator;
class Zakres implements Iterable<Integer> {
final int start;
final int koniec;
public Zakres(final int start, final int koniec) {
this.start = start;
this.koniec = koniec;
}
@Override
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
int aktualny = start;
@Override
public boolean hasNext() {
return aktualny <= koniec;
}
@Override
public Integer next() {
return aktualny++;
}
@Override
public void remove() {
throw new UnsupportedOperationException("Illegal action.");
}
};
}
}
public class Main {
public static void main(String[] args) {
Zakres zakres = new Zakres(5, 8);
for (int i : zakres) {
System.out.println(i);
}
for (int i : zakres) {
System.out.println(i);
}
for (int i : zakres) {
System.out.println(i);
}
}
}
Wynik działania: http://ideone.com/avtl9i
Moja implementacja Iterable (czyli tutaj Zakres) jest zgodna ze specyfikacją, a więc zwrócony Iterator nie zmienia stanu obiektu iterowanego podczas iterowania (wyjątek stanowi usuwanie za pomocą metody remove, ale tutaj nie jest zaimplementowana). Dlatego mogę iterować po jednym i tym samym Zakresie wiele razy.
Kod:
for (int i : zakres) {
System.out.println(i);
}
Jest równoznaczny z:
Iterator<Integer> iterator = zakres.iterator();
while (iterator.hasNext()) {
int i = iterator.next();
System.out.println(i);
}
Tzn każdy foreach to osobne stworzenie Iteratora.