Iterator Design Pattern Example in Java
The Iterator design pattern provides a way to access the elements of an aggregate object (such as a collection) sequentially without exposing its underlying representation. The pattern decouples the collection from the code that uses it, making it easy to change the collection implementation without affecting the client code.
A real-world example of the Iterator pattern in Java can be seen in the Java Collection Framework.
Table of Content :
- Introduction
- What is Iterator Design Pattern
- Iterator pattern Design participants
- Iterator design pattern example
- Iterator design pattern advantages
- Conclusion
The Collection Framework provides a set of interfaces and classes for working with collections of objects, such as lists, sets, and maps. These collections are implemented using different data structures, such as arrays, linked lists, and hash tables.
To iterate over the elements of a collection, the Collection Framework provides an Iterator interface and its concrete implementations, such as ArrayList and HashSet. The Iterator interface defines the methods for iterating over the elements of a collection, including hasNext() and next(). The concrete implementations provide the actual implementation for these methods based on the data structure used.
package com.javacodestuffs.core.java.iterator.pattern;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class ListIteratorExample {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("Bala");
names.add("Anna");
names.add("Charlie");
names.add("Joseph");
names.add("Sara");
names.add("Shivani");
ListIterator<String> iterator = names.listIterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
output:
Bala
Anna
Charlie
Joseph
Sara
Shivani
Iterator pattern Design participants
The Iterator pattern consists of four Design participants:
- Iterator interface: defines the methods for accessing the elements of the collection.
- Concrete Iterator: implements the Iterator interface and provides the implementation for the methods.
- Aggregate interface: defines the methods for creating an Iterator object.
- Concrete Aggregate: implements the Aggregate interface and provides the implementation for the Iterator creation method.
Iterator design pattern example
Here's an example implementation of the Iterator design pattern in Java:
Iterator interface
package com.javacodestuffs.core.java.iterator.pattern;
public interface Iterator<T> {
boolean hasNext();
T next();
}
Concrete Iterator
package com.javacodestuffs.core.java.iterator.pattern;
import java.util.NoSuchElementException;
public class ArrayIterator<T> implements Iterator<T> {
private final T[] array;
private int index;
public ArrayIterator(T[] array) {
this.array = array;
this.index = 0;
}
@Override
public boolean hasNext() {
return index < array.length;
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return array[index++];
}
}
Aggregate interface
package com.javacodestuffs.core.java.iterator.pattern;
public interface Aggregate<T> {
Iterator<T> createIterator();
}
Concrete Aggregate
package com.javacodestuffs.core.java.iterator.pattern;
public class ArrayCollection<T> implements Aggregate<T> {
private final T[] array;
public ArrayCollection(T[] array) {
this.array = array;
}
@Override
public Iterator<T>createIterator() {
return new ArrayIterator<>(array);
}
}
IteratorClient
package com.javacodestuffs.core.java.iterator.pattern;
public class IteratorClient {
public static void main(String[] args) {
System.out.println("----------- Interator for Strings -----------");
String[] names = { "Anna", "Bala", "Sara", "Joseph", "Shivani" };
ArrayCollection<String> collection = new ArrayCollection<>(names);
Iterator<String> iterator = collection.createIterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
Integer[] intList = { 101, 105, 50, 1001, 25 };
System.out.println("-----------Interator for Integer-----------");
ArrayCollection&Integer> intCollection = new ArrayCollection<>(intList);
Iterator&Integer> intIterator = intCollection.createIterator();
while (intIterator.hasNext()) {
System.out.println(intIterator.next());
}
}
}
In this implementation, the Iterator interface defines the hasNext and next methods for accessing the elements of the collection. The ArrayIterator class is the concrete iterator, which implements the Iterator interface and provides the implementation for the methods.
The Aggregate interface defines the createIterator method for creating an Iterator object.
The ArrayCollection class is the concrete aggregate, which implements the Aggregate interface and provides the implementation for the createIterator method.
The IteratorClient code creates an instance of the ArrayCollection, gets an Iterator object using the createIterator method, and then iterates over the elements using the hasNext and next methods of the Iterator.
Iterator design pattern advantages
The Iterator design pattern offers several advantages, including:
- Encapsulating the collection : The Iterator design pattern encapsulates the collection's implementation details and provides a standard interface for iterating over its elements. This allows the collection to change its implementation without affecting the client code.
- Simplicity: The pattern simplifies the code by separating the iteration logic from the collection. It also eliminates the need for boilerplate code to iterate over collections.
- Flexibility: The pattern allows multiple iterations to be in progress at the same time without interfering with each other. It also allows the elements to be accessed in different orders, such as reverse or random order.
- Efficiency: The pattern enables lazy iteration, where the elements are retrieved only when requested, rather than all at once. This improves the efficiency of the application and reduces memory usage.
- Compatibility: The Iterator design pattern is compatible with other design patterns, such as the Composite and Factory Method patterns. It can also be used with different types of collections, such as arrays, lists, and sets.
Overall, the Iterator design pattern promotes code reuse, improves code maintainability, and enhances the performance of the application by providing an efficient way to iterate over collections.
Conclusion
In this article we have seen Iterator Design Pattern . We also seen how to use Factory Design Pattern in java with examples.
All the classes code is available on GitHub.
0 Comments
Post a Comment