Working With Design Patterns: Iterator
The enhanced-for loop takes advantage of the ability to bind a class to parameterized types, eliminating the need for any casting in the client solution. Even better, programmers can provide enhanced-for loop support in their classes by having them implement the Iterable interface:
class Menu implements Iterable<String> { private List<String> items = new ArrayList<String>(); public void add(String item) { items.add(item); } @Override public Iterator<String> iterator() { return items.iterator(); } }
By having Menu implement Iterable, clients can code simple for-each loops to traverse all the menu items:
Menu menu = new Menu(); menu.add("Beef Stroganoff"); menu.add("Filet Mignon"); menu.add("Rice with Tofu"); for (String item: menu) { // ... }
The enhanced-for loop syntax is about as concise as Java could allow, at least until the possible introduction of closures in Java 7.
Exploring Enhanced-For
I appreciate the enhanced-for loop: Anything that makes the code more concise and expressive at the same time is good. But, it doesn't quite cover everything. If I want to iterate through the numbers 0 through 9, I'm still stuck with the classic C-style for the loop idiom:
for (int i = 0; i < 9; i++) ...
But, what if I considered representing the range as a new abstraction:
Sequence s = new Sequence(0, 9);
At that point, I could have the Sequence class implement Iterable<Integer>, thus supporting use of the enhanced-for loop:
for (int i: new Sequence(0, 9)) ...
With the addition of auto-unboxing, this makes for a very concise client interface. Listing 1 shows the complete implementation for a Sequence class:
Listing 1: The Sequence class
import java.util.Iterator; public class Sequence implements Iterable<Integer> { private int start; private int stop; private int increment = 1; public Sequence(int start, int stop) { this.start = start; this.stop = stop; } public Sequence(int start, int stop, int increment) { this(start, stop); this.increment = increment; } public Iterator<Integer> iterator() { return new SequenceIterator(); } private class SequenceIterator implements Iterator<Integer> { private int count = start; public boolean hasNext() { return count <= stop; } public Integer next() { int result = count; count += increment; return result; } public void remove() { throw new UnsupportedOperationException(); } } }
The Sequence class also provides the ability to skip elements. A set of tests demonstrating use of the Sequence class appears in Listing 2.
Page 2 of 3
This article was originally published on July 9, 2008