How do you create and use an iterator in Python and in Java, and how does each signal the end?
Python: it = iter(iterable), then next(it); the end is signalled by raising StopIteration. Java: Iterator<T> it = iterable.iterator(), check it.hasNext() before it.next(); the end is hasNext() == false, and calling next() anyway throws NoSuchElementException.
| Python | Java | |
|---|---|---|
| Create | it = iter(iterable) (calls iterable.__iter__()) |
Iterator<T> it = iterable.iterator() |
| Get next | next(it) (calls it.__next__()) |
it.next() |
| Detect the end | next raises StopIteration |
it.hasNext() returns false |
| Past the end | — (the exception is the signal) | next() throws NoSuchElementException |
The two styles reflect a design difference. Java asks first: you check hasNext() and only then call next(), so running off the end is a programming error. Python tries and catches: you just call next(), and the exception is the normal end-of-data signal.
In everyday code you rarely write either by hand. Python's for x in xs: calls iter once and next repeatedly, silently catching StopIteration. Java's for (T x : xs) calls iterator() and loops on hasNext()/next().
Go deeper:
Python iterator types — the
__iter__/__next__protocol andStopIteration.java.util.Iterator —
hasNext,next,removeand the documented exceptions.