Iterator allows a way to access elements/children of an aggregate object in sequence while hiding the actual internal data structure used.
In Java language, iterators are an integral part of collection frameworks and they are implementations of this design pattern.
Iterators are stateful, meaning an iterator object remembers its position while iterating
Iterators can become out of sync if the underlying collection is changed while code is using iterator
2. Description
2.1 Implementation
Iterator has methods to check whether there is an element available in sequence and to get that element
Iterator is typically an inner class in our concrete aggregate. Making it an inner class makes it easy to access internal data structures
Concrete iterator needs to maintain state to tell its position in the collection of aggregate. If the inner collection changes, it can throw an exception to indicate an invalid state.
2.2 Consideration
2.2.1 Implementation
Detecting change to underlying data structure while some code is using an iterator is important to notify to the client because then our iterator may not work correctly
Having our iterator implementation as inner class makes it easy to access an internal collection of aggregate objects
2.2.2 Design
Always prefer iterator interface so you can change the implementation without affecting client
Iterators have many applications where a collection is not directly used but we still want to give sequential access to information, for example, maybe for reading lines from a file, from the network.
2.3 Pitfalls
Access to an index during iteration is not readily available like we have in a for loop
Making modifications to the collection while someone is using an iterator often makes that iterator instance invalid as its state may not be valid.
3. Usage
The iterator classes in Java's collection framework
java.util.Scanner class
javax.xml.stream.XMLEventReader class
4. Example
//Iterator interface allowing to iterate over
//values of an aggregate
interface Iterator<T> {
boolean hasNext();
T next();
}
//This enum represents the aggregate from iterator pattern
enum ThemeColor {
RED,
ORANGE,
BLACK,
WHITE;
public static Iterator<ThemeColor> getIterator() {
return new ThemeColorIterator();
}
// banning access from outside
private static class ThemeColorIterator implements Iterator<ThemeColor> {
private int position;
@Override
public boolean hasNext() {
return position < ThemeColor.values().length;
}
@Override
public ThemeColor next() {
return ThemeColor.values()[position++];
}
}
}
public class Client {
public static void main(String[] args) {
Iterator<ThemeColor> iter = ThemeColor.getIterator();
while(iter.hasNext()) {
System.out.println(iter.next());
}
}
}