Iterator Design Pattern in Java
Learn Iterator Design Pattern in Java with Collection traversal, Java Iterator API, custom iterators, internal vs external iteration, enterprise examples, UML diagrams, and interview questions.
What You Will Learn
- What is Iterator Pattern?
- Why Iterator Pattern is Needed
- Iterator Architecture
- Java Iterator API
- Custom Iterator Implementation
- Internal vs External Iteration
- Collection Framework Examples
- Enterprise Use Cases
- Benefits and Limitations
- Interview Questions
Introduction
Suppose you have:
List of Customers
List of Orders
List of Employees
List of Transactions
You need to traverse them one by one.
Without Iterator Pattern:
Customer customer1 = customers.get(0);
Customer customer2 = customers.get(1);
Customer customer3 = customers.get(2);
This approach is difficult and tightly coupled to the collection structure.
Iterator Pattern provides a standard way to traverse collections without exposing their internal implementation.
What is Iterator Pattern?
Iterator is a Behavioral Design Pattern that provides a way to access elements of a collection sequentially without exposing its internal structure.
Simple view:
Collection
↓
Iterator
↓
Elements
Purpose of Iterator Pattern
Main goal:
Traverse Collections
Without Knowing
Their Internal Structure
Real World Analogy
Think about a TV Remote.
You do not know:
How Channels Are Stored
You simply press:
Next Channel
Previous Channel
The remote acts like an Iterator.
Iterator Architecture
flowchart LR
A[Collection]
B[Iterator]
C[Elements]
A --> B
B --> C
Problem Without Iterator
flowchart LR
A[Client]
B[List]
C[Array]
D[Set]
A --> B
A --> C
A --> D
Client needs separate traversal logic.
Solution With Iterator
flowchart LR
A[Client]
B[Iterator]
C[List]
D[Array]
E[Set]
A --> B
B --> C
B --> D
B --> E
Client always uses Iterator.
Key Components
Iterator
Defines traversal operations.
Concrete Iterator
Actual implementation.
Aggregate
Collection object.
Concrete Aggregate
Actual collection implementation.
UML Diagram
classDiagram
class Iterator {
+hasNext()
+next()
}
class ConcreteIterator
class Aggregate {
+createIterator()
}
class ConcreteAggregate
Iterator <|.. ConcreteIterator
Aggregate <|.. ConcreteAggregate
Java Iterator Interface
Java provides built-in Iterator.
public interface Iterator<E> {
boolean hasNext();
E next();
void remove();
}
Common Methods
hasNext()
Checks if more elements exist.
iterator.hasNext();
next()
Returns next element.
iterator.next();
remove()
Removes current element.
iterator.remove();
List Example
List<String> names =
List.of(
"John",
"David",
"Mike");
Traversal:
Iterator<String> iterator =
names.iterator();
while(iterator.hasNext()) {
System.out.println(
iterator.next());
}
Output
John
David
Mike
Execution Flow
flowchart LR
A[John]
B[David]
C[Mike]
A --> B
B --> C
Custom Iterator Example
Suppose we have employee records.
Employee Class
public class Employee {
private String name;
public Employee(
String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Iterator Interface
public interface EmployeeIterator {
boolean hasNext();
Employee next();
}
Employee Collection
public class EmployeeCollection {
private Employee[] employees;
public EmployeeCollection(
Employee[] employees) {
this.employees = employees;
}
public EmployeeIterator iterator() {
return new EmployeeIteratorImpl(
employees);
}
}
Concrete Iterator
public class EmployeeIteratorImpl
implements EmployeeIterator {
private Employee[] employees;
private int position;
public EmployeeIteratorImpl(
Employee[] employees) {
this.employees = employees;
}
@Override
public boolean hasNext() {
return position < employees.length;
}
@Override
public Employee next() {
return employees[position++];
}
}
Client Code
public class IteratorDemo {
public static void main(
String[] args) {
Employee[] employees = {
new Employee("John"),
new Employee("Mike"),
new Employee("David")
};
EmployeeCollection collection =
new EmployeeCollection(
employees);
EmployeeIterator iterator =
collection.iterator();
while(iterator.hasNext()) {
System.out.println(
iterator.next()
.getName());
}
}
}
Output
John
Mike
David
Iterator Flow
sequenceDiagram
Client->>Collection: iterator()
Collection-->>Client: Iterator
Client->>Iterator: hasNext()
Client->>Iterator: next()
Iterator-->>Client: Employee
Internal vs External Iteration
External Iteration
Developer controls traversal.
Iterator<String> iterator =
list.iterator();
while(iterator.hasNext()) {
System.out.println(
iterator.next());
}
Internal Iteration
Framework controls traversal.
list.forEach(
System.out::println);
Comparison
| Feature | External | Internal |
|---|---|---|
| Control | Developer | Framework |
| Complexity | More | Less |
| Java Example | Iterator | Streams |
Java Stream Example
employees.stream()
.forEach(
System.out::println);
Streams internally use iterator concepts.
Banking Example
Transaction Processing:
Transaction 1
Transaction 2
Transaction 3
Transaction 4
Iterator processes records one by one.
Banking Flow
flowchart LR
A[Transaction 1]
B[Transaction 2]
C[Transaction 3]
D[Transaction 4]
A --> B
B --> C
C --> D
Insurance Example
Policy Processing:
Policy 1
Policy 2
Policy 3
Policy 4
Iterator processes policies sequentially.
Batch Job Example
Spring Batch reads:
Millions of Records
using iterator-like mechanisms.
ItemReader
works similarly.
Spring Batch Flow
flowchart LR
A[Item Reader]
B[Processor]
C[Writer]
A --> B
B --> C
JDBC Example
ResultSet behaves like an iterator.
while(resultSet.next()) {
}
Each row is processed sequentially.
Real Enterprise Examples
Banking
Transaction Processing
Statement Generation
Insurance
Policy Processing
Claim Processing
E-Commerce
Order Processing
Inventory Updates
Big Data
Chunk Processing
Streaming Data
Java Collections Using Iterator
ArrayList
LinkedList
HashSet
TreeSet
HashMap
All support iterator traversal.
Benefits
✅ Uniform Traversal Interface
✅ Hides Internal Structure
✅ Supports Multiple Collections
✅ Cleaner Code
✅ Easy Collection Navigation
✅ Supports Lazy Traversal
Limitations
❌ Additional Objects
❌ Traversal Only
❌ Not Ideal For Complex Queries
When To Use
Use Iterator when:
- Traversing collections
- Collection implementation should be hidden
- Multiple traversal strategies are required
- Sequential processing is needed
When Not To Use
Avoid when:
- Direct access is faster
- Collection is extremely simple
- Streams provide better readability
Iterator vs For Loop
| Feature | Iterator | For Loop |
|---|---|---|
| Collection Agnostic | Yes | No |
| Works With Sets | Yes | No |
| Encapsulation | Better | Poor |
| Flexibility | High | Medium |
Iterator vs Stream
| Feature | Iterator | Stream |
|---|---|---|
| Style | External Iteration | Internal Iteration |
| Control | High | Medium |
| Parallelism | No | Yes |
| Readability | Medium | High |
Interview Questions
What is Iterator Pattern?
A behavioral pattern that provides sequential access to collection elements.
Why Use Iterator?
To traverse collections without exposing their internal implementation.
What are the Main Methods?
hasNext()
next()
remove()
Real Java Example?
java.util.Iterator
Difference Between Iterator and Stream?
Iterator uses external iteration while Streams use internal iteration.
Enterprise Example?
Spring Batch ItemReader and JDBC ResultSet.
Key Takeaways
- Iterator is a Behavioral Design Pattern.
- Provides sequential traversal of collections.
- Hides internal collection structure.
- Java Collections Framework heavily uses Iterator.
- Streams are built on iterator concepts.
- Common in Spring Batch, JDBC, and enterprise batch processing.
- Makes collection traversal flexible and reusable.