dcsimg
November 29, 2020
Hot Topics:

Working With Design Patterns: Iterator

  • By Jeff Langr
  • Send Email »
  • More Articles »

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

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.


Thanks for your registration, follow us on our social networks to keep up-to-date