π Table of Contents
π Iterator Design Pattern in Java β Explained with a Custom User Management Example
π What is the Iterator Design Pattern?
The Iterator Design Pattern is a behavioral design pattern that provides a way to sequentially access elements of a collection without exposing its internal structure.
Think of it as a clean way to loop through complex data structures like trees, graphs, or even simple collections, without the caller needing to know how the elements are stored internally.
π§βπ€βπ§ Key Participants
In the context of our example:
Pattern Role | Java Class |
---|---|
Iterator | MyIterator |
Concrete Iterator | MyIneratorImpl |
Aggregate | UserManagement |
Concrete Elements | User |
π Real world Analogy
Think of user management in a web app. The admin doesnβt care how users are stored (array, list, map). They just want to browse user profiles one by one β next user, next user...
Thatβs what the iterator does β lets the admin move across users without exposing the backend logic.
π UML Diagram (Text Format)
+--------------------+ +------------------------+
| MyIterator |<------+ MyIneratorImpl |
+--------------------+ +------------------------+
| +hasNext():boolean | | -list: List<User> |
| +next(): Object | | -index: int |
+--------------------+ | +hasNext() |
| +next() |
+------------------------+
+------------------------+
| UserManagement |
+------------------------+
| -list: List<User> |
| +addUser(User) |
| +getIterator():Iterator|
+------------------------+
+-------------+
| User |
+-------------+
| -name |
| -emailID |
| +getName() |
| +getEmailID()|
+-------------+
π» Full Java Implementation
1. User
β The Element Object
package org.example;
public class User {
private String name;
private String emailID;
public User(String name, String emailID) {
this.name = name;
this.emailID = emailID;
}
public String getName() {
return name;
}
public String getEmailID() {
return emailID;
}
}
2. MyIterator
β The Iterator Interface
package org.example;
public interface MyIterator {
boolean hasNext();
Object next();
}
3. MyIneratorImpl
β Concrete Iterator
package org.example;
import java.util.List;
public class MyIneratorImpl implements MyIterator {
private List<User> list;
private int index;
public MyIneratorImpl(List<User> list) {
this.list = list;
this.index = 0;
}
public boolean hasNext() {
return index < list.size();
}
public Object next() {
return list.get(index++);
}
}
4. UserManagement
β Aggregate Class
package org.example;
import java.util.ArrayList;
public class UserManagement {
private ArrayList<User> list = new ArrayList<>();
public void addUser(User user) {
list.add(user);
}
public MyIterator getIterator() {
return new MyIneratorImpl(list);
}
}
5. Main
β Client Code
package org.example;
public class Main {
public static void main(String[] args) {
UserManagement userManagement = new UserManagement();
User user1 = new User("User1", "[email protected]");
User user2 = new User("User2", "[email protected]");
userManagement.addUser(user1);
userManagement.addUser(user2);
MyIterator iterator = userManagement.getIterator();
while (iterator.hasNext()) {
User user = (User) iterator.next();
System.out.println(user.getName() + " - " + user.getEmailID());
}
}
}
π Use Cases in Real-World Systems
- Traversing elements in custom collection classes
- Paging through user records, log entries, or audit history
- Abstracting tree traversal in file systems or DOM trees
- Iterating over results of complex computations
β Advantages
- Decouples iteration logic from collection
- Allows different traversal strategies (e.g., reverse, conditional)
- Enables multiple iterators on same collection
- Supports lazy evaluation if needed
β Disadvantages
- Additional boilerplate code for small or simple collections
- Requires maintenance of custom iterator classes
- Can be error-prone if
next()
used withouthasNext()
π§ When to Use and When Not To Use
β Use When:
- You want to traverse a collection in a standard way
- Internal data structure should remain hidden
- Multiple types of iteration are needed
β Avoid When:
- Javaβs built-in
Iterator
or enhanced for-loop suffices - Performance is critical and abstraction adds overhead
- Collections are simple and donβt require abstraction
π Internal vs External Iterators
Type | Description | Java Example |
---|---|---|
External | Client controls iteration (our example) | Custom iterator, while (hasNext)
|
Internal | Collection controls iteration |
forEach() , Streams API |
π Comparison with Java Built-in Iterators
Feature | Our Custom MyIterator
|
Java's Built-in Iterator
|
---|---|---|
Interface name | MyIterator |
java.util.Iterator |
Generic support | β (Object) | β
(Iterator<T> ) |
Additional methods | β | β
(remove() , forEachRemaining ) |
Loop compatibility | β | β
(Iterable ) supports for-each |
Preferred in practice | β | β (less code, more power) |
π§βπ« Best Practices and Pitfalls
β Best Practices:
- Add type safety with generics (
MyIterator<T>
) - Check
hasNext()
before callingnext()
- Prefer
Iterable<T>
interface to support enhanced for-loop - Keep iterator logic inside collection class if possible
β οΈ Pitfalls:
- Donβt call
next()
withouthasNext()
β may causeIndexOutOfBoundsException
- Donβt modify list during iteration (unless supported)
- Avoid exposing mutable internal data via
next()
π Alternatives
Alternative | Use When |
---|---|
Enhanced for-loop | When implementing Iterable<T>
|
Java Streams | When using functional and lazy operations |
ListIterator | When bidirectional or modifying iteration is needed |
Reactive Streams | For async event-based data flow |
π Summary (Bullet Points)
- The Iterator Pattern provides a standard way to iterate collections without exposing internals.
- We implemented
MyIterator
,MyIneratorImpl
,UserManagement
, andUser
to demonstrate it. - Separation of concerns: collection logic and iteration logic are independent.
- Java provides built-in
Iterator
/Iterable
that are preferable in production. - Consider using Streams or for-each for simpler use cases.
- Useful in designing robust and flexible custom collection classes.
π Explore More Design Patterns in Java
- π Mastering the Singleton Design Pattern in Java β A Complete Guide
- β οΈ Why You Should Avoid Singleton Pattern in Modern Java Projects
- π Factory Design Pattern in Java β A Complete Guide
- π§° Abstract Factory Design Pattern in Java β Complete Guide with Examples
- π§± Builder Design Pattern in Java β A Complete Guide
- π Observer Design Pattern in Java β Complete Guide
- π Adapter Design Pattern in Java β A Complete Guide
More Details:
Get all articles related to system design
Hastag: SystemDesignWithZeeshanAli
Git: https://github.com/ZeeshanAli-0704/SystemDesignWithZeeshanAli
Top comments (0)