Iterator
Beginner · 12 min read · Low-Level Design, Behavioral Patterns
Traversing collections without exposing their internals.
The idea in plain words
An Iterator lets you walk through a collection one item at a time, without knowing how the collection stores its items inside (array, tree, pages from an API).
The problem
Collections differ internally: arrays, linked lists, trees, graphs, or data that arrives page by page from an API. Clients want to "go through every element" without knowing which.
The solution
Extract traversal into a separate iterator object that tracks its own position. The collection provides iterators; clients use the common interface.
Correctness rules for Java iterators
Lazy iteration over large or remote data
Iterators shine when data shouldn't be loaded all at once — for example, a paginated API:
Internal vs external iterators
Pros and cons
Related patterns
Combining iterators
Many interview questions ask you to build an iterator out of other iterators. Two useful building blocks:
Iterator problems in coding rounds
These come up often, and each is a small variation on the techniques above. You can solve them with tests here:
From iterators to streams
Java 8 added Spliterator ("splittable iterator"), which can split its remaining elements in two so a parallel stream can process the halves on different threads. Any Iterable can become a stream with StreamSupport.stream(iterable.spliterator(), false).
Interview questions
- What's the difference between fail-fast and fail-safe iterators?
- Implement an iterator that flattens a list of lists.
- Why must hasNext() be idempotent, and how does a filtering iterator achieve it?
Further reading
Key takeaways
- Iterator separates traversal from the collection; each iterator keeps its own position.
- Java's Iterable/Iterator are the pattern; implement next() to throw NoSuchElementException and keep hasNext() idempotent.
- Know fail-fast vs weakly consistent iteration.
- Use iterators for lazy traversal of large, tree-shaped or paginated data.
- Build complex traversals by composing iterators (round robin, filtering, flattening), keeping lookahead in the iterator.