The Iterator Pattern is a behavioral design pattern that provides a way to sequentially access the elements of a collection without exposing its underlying representation.

Instead of allowing clients to traverse a collection directly, the collection provides an iterator object that encapsulates the traversal logic. This keeps the collection and traversal algorithm independent of each other.

Multiple iterators can traverse the same collection simultaneously while maintaining their own traversal state.

The Iterator Pattern is commonly used for traversing collections, trees, graphs, custom data structures, and database result sets.

Structure

The Iterator Pattern consists of the following participants.

1. The Iterator defines methods for traversing a collection.
2. The Concrete Iterator implements the traversal logic.
3. The Aggregate defines a method for creating an iterator.
4. The Concrete Aggregate stores the collection elements and creates iterator objects.
5. The Client traverses the collection using the iterator.

Java Implementation

Suppose an application stores employee names in a collection. The client should iterate through the employees without knowing how they are internally stored.

Create the iterator interface.
public interface Iterator {
    boolean hasNext();
    String next();
}
Create the aggregate.
public interface EmployeeCollection {
    Iterator iterator();
}
Create the concrete aggregate.
public class CompanyEmployees implements EmployeeCollection {
    private final String[] employees = {
            "Alice",
            "Bob",
            "Charlie"
    };
    @Override
    public Iterator iterator() {
        return new EmployeeIterator();
    }
    private class EmployeeIterator implements Iterator {
        private int index = 0;

        @Override
        public boolean hasNext() {
            return index < employees.length;
        }

        @Override
        public String next() {
            return employees[index++];
        }
    }
}
The client traverses the collection.
public class Main {
    public static void main(String[] args) {

        EmployeeCollection employees = new CompanyEmployees();
        Iterator iterator = employees.iterator();

        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}
Output:
Alice
Bob
Charlie

How It Works?

The client interacts only with the Iterator interface and never accesses the internal representation of the collection.

The CompanyEmployees class creates an EmployeeIterator, which maintains the current traversal position internally.

The client repeatedly invokes hasNext() to determine whether more elements are available and next() to retrieve each element in sequence.

Because the traversal logic is encapsulated inside the iterator, the underlying collection can change its implementation without affecting client code. Different iterator implementations can also provide alternative traversal orders.

Advantages

1. It separates traversal logic from the collection implementation.
2. The internal representation of the collection remains hidden from the client.
3. Multiple iterators can traverse the same collection independently.
4. New traversal algorithms can be introduced without modifying the collection.

Disadvantages

1. The pattern introduces additional iterator classes.
2. Creating custom iterators for simple collections may add unnecessary complexity.
3. Synchronization may be required when iterating over collections that are modified concurrently.

JDK Examples

The Iterator Pattern appears throughout the Java ecosystem.

1. The java.util.Iterator interface provides sequential access to elements in Java collections such as ArrayList, HashSet, and LinkedList.

2. The enhanced for-each loop internally uses the java.util.Iterator interface to traverse objects that implement the Iterable interface.

Summary

The Iterator Pattern provides a standard way to traverse a collection without exposing its internal implementation.

By encapsulating traversal logic inside iterator objects, the pattern promotes loose coupling, improves encapsulation, and allows collections to support multiple traversal strategies while keeping client code simple.
Nagesh Chauhan

Nagesh Chauhan

Principal Software Engineer • Java • Python • Distributed Systems • AI/ML

Principal Software Engineer with 14+ years of experience designing and delivering large-scale distributed systems, cloud-native applications, and AI-powered platforms.

Passionate about solving complex engineering problems using strong data structures and algorithms, along with expertise in Java, Spring Boot, Python, System Design, Microservices, Cloud, Kafka, Elasticsearch, and Generative AI.

Share this Article

💬 Comments

Join the Discussion