Java > Design Patterns in Java > Behavioral Patterns > Iterator Pattern
External Iterator Example
This snippet illustrates an external iterator, explicitly managed by the client code. The `WordIterator` allows you to traverse the words in a given sentence.
Word Iterator
The `WordIterator` class splits the given sentence into words and then iterates through them using the `hasNext()` and `next()` methods. The `Sentence` class acts as the aggregate and provides the `getIterator()` method to obtain the `WordIterator` instance. The main method then uses this iterator to print each word in the sentence. This differs from a Java Collection Library Iterator which would normally be returned from the Collection implementation class.
import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;
class WordIterator implements Iterator<String> {
private String[] words;
private int index = 0;
public WordIterator(String sentence) {
this.words = sentence.split(" ");
}
@Override
public boolean hasNext() {
return index < words.length;
}
@Override
public String next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return words[index++];
}
}
class Sentence {
private String sentence;
public Sentence(String sentence) {
this.sentence = sentence;
}
public WordIterator getIterator() {
return new WordIterator(sentence);
}
}
public class ExternalIteratorDemo {
public static void main(String[] args) {
Sentence sentence = new Sentence("This is a sample sentence");
WordIterator iterator = sentence.getIterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
Concepts Demonstrated
This example showcases the core components of the Iterator pattern: the iterator interface (`Iterator`), the concrete iterator (`WordIterator`), and the aggregate (`Sentence`). The client code explicitly manages the iterator's lifecycle.
Iterator in Java Collection
Explanation: This code demonstrates how to use the Iterator provided by the Java Collection Framework. We create an ArrayList of names and obtain an Iterator from it. We then use the hasNext() and next() methods to traverse the list and print each name. This is a common use case of the Iterator pattern in Java.
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class CollectionIterator {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
names.add("Charlie");
// Using iterator to traverse the list
Iterator<String> iterator = names.iterator();
while (iterator.hasNext()) {
String name = iterator.next();
System.out.println(name);
}
}
}
When to Use
Use this external iterator pattern when you need fine-grained control over the iteration process or when you need to customize the iteration behavior. This is useful when iterating over data structures that do not implement the Collection interface.
Pros
Cons
FAQ
-
What happens if the sentence is empty?
If the sentence is empty, the `words` array will be empty, and `hasNext()` will immediately return `false`. `next()` will throw `NoSuchElementException` if called on an empty iterator. -
Is the `WordIterator` thread-safe?
No, the `WordIterator` is not thread-safe. If multiple threads access and modify the underlying sentence or the iterator's state concurrently, it can lead to unexpected behavior. Thread-safe iterators require synchronization mechanisms.