🔍 Iterator Design Pattern – In-Depth Guide

🔍 Iterator Design Pattern – In-Depth Guide

1. What is the Iterator Pattern?

The Iterator Design Pattern is a behavioral design pattern that provides a way to access elements of a collection (list, array, map, tree, etc.) sequentially without exposing the internal representation.

💡 Core Idea:

“You don’t need to know how a collection is built, you just need a standard way to loop through it.”

2. Example 🏡

Imagine a TV remote with channel up/down buttons:

  • You don’t care how the TV stores channels internally.
  • You just keep pressing “next” to iterate through channels.
  • The remote (iterator) provides a simple way to access one channel at a time.


3. When to Use Iterator Pattern?

✅ To traverse different kinds of collections in a uniform way. ✅ To provide sequential access without exposing internal data structures. ✅ When you want to decouple iteration logic from the collection itself.


4. UML Structure 🔗

  • Iterator (Interface) → Defines methods like hasNext(), next().
  • ConcreteIterator → Implements traversal logic.
  • Aggregate (Collection Interface) → Defines method to create an iterator.
  • ConcreteAggregate → Implements collection and returns iterator.
  • Client → Uses iterator to traverse elements.


5. Simple Example (Custom Collection)

// Iterator Interface
interface Iterator<T> {
    boolean hasNext();
    T next();
}

// Aggregate Interface
interface Container<T> {
    Iterator<T> getIterator();
}

// Concrete Aggregate
class NameRepository implements Container<String> {
    private String[] names = {"Arjun", "Suraj", "Neha", "Rahul"};

    public Iterator<String> getIterator() {
        return new NameIterator();
    }

    // Concrete Iterator
    private class NameIterator implements Iterator<String> {
        int index = 0;

        public boolean hasNext() {
            return index < names.length;
        }

        public String next() {
            return hasNext() ? names[index++] : null;
        }
    }
}

// Client
public class IteratorDemo {
    public static void main(String[] args) {
        NameRepository repo = new NameRepository();
        Iterator<String> iterator = repo.getIterator();

        while (iterator.hasNext()) {
            System.out.println("Name: " + iterator.next());
        }
    }
}
        

Output:

Name: Arjun  
Name: Suraj  
Name: Neha  
Name: Rahul  
        

6. Real-World / Production Use Cases 🚀

a) Collections Framework (Java, C#, Python, etc.)

  • In Java, classes like ArrayList, HashSet, HashMap use Iterators to traverse without exposing internal structure.
  • Example:

b) Tree / Graph Traversals

  • DFS, BFS iterators can be implemented without exposing internal nodes.

c) Streaming Data / APIs

  • Iterators are used in pagination of APIs (e.g., fetching 50 records at a time).

d) Database Cursors

  • SQL engines provide cursors which work like iterators on result sets.


7. Advantages ✅

  • Provides a uniform way to traverse collections.
  • Hides internal representation of data structures.
  • Supports multiple traversals (forward, backward, skip, custom).
  • Increases flexibility and clean code.

8. Limitations ⚠️

  • Overhead of creating multiple iterators for large collections.
  • Single-threaded iterators may need extra handling for concurrency.


9. Real Production Analogy 🌍

Think of Netflix’s “Next Episode” button:

  • You don’t care how episodes are stored.
  • The iterator (button) gives you the next episode sequentially.


Conclusion: The Iterator Pattern is everywhere — in Java’s Iterable, Python’s __iter__, C#’s IEnumerator, even database cursors. It abstracts traversal so developers can focus on logic, not structure.

To view or add a comment, sign in

More articles by Suraj Singh

Others also viewed

Explore content categories