π 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", "user1@gmail.com"); User user2 = new User("User2", "user2@gmail.com"); 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
- π Strategy Design Pattern in Java β A Complete Guide
- π Decorator Design Pattern in Java β Complete Guide
More Details:
Get all articles related to system design
Hastag: SystemDesignWithZeeshanAli
Git: https://github.com/ZeeshanAli-0704/SystemDesignWithZeeshanAli
Top comments (0)