CMPS 144: Notes on the Iterator Interface

The java.util package includes a generic interface called Iterator, which essentially looks like this:

public interface Iterator<E> {

   // observer
   // --------

   /* Reports whether there are more elements in the iteration.
   */
   boolean hasNext();


   // observer/mutator
   // ----------------

   /* If hasNext(), returns the next element in the iteration.
   ** If !hasNext(), throws a NoSuchElementException.
   */
   E next();
}

An example of a familiar class that implements this interface is java.util.Scanner, which, specifically, implements Iterator<String>. As you will recall, when the next() method is invoked upon a Scanner object, the String returned is the next token from the source of input to which that scanner is attached (which is typically either the keyboard or a text file).

In general, any class whose instances represent a collection of objects is a good candidate for either implementing the Iterator interface or for having a method that returns an iterator over that collection, as doing so provides its clients with a convenient way to examine each of the objects in the collection, one at a time.

As an example, consider a Java class whose instances represent sets of integers. Here is a skeleton:

import java.util.Iterator;

/* An instance of this class represents a set of integers.
*/
public class SetOfIntegers {

   // observer
   // --------

   /* Reports whether the given integer is a member of this set.
   */
   public boolean isMember(int k) { ... }

   // mutators
   // --------

   /* Ensures that the given integer is a member of this set.
   ** post: isMember(k)
   */
   public include(int k) { ... }

   /* Ensures that the given integer is not a member of this set.
   ** post: !isMember(k)
   */
   public exclude(int k) { ... }

   // iterator
   // --------

   /* Returns an iterator over this set.
   */
   public Iterator<Integer> iterator() { ... }

}

Now consider this client of SetOfIntegers, which provides some utility methods pertaining to instances of that class. Notice how it makes use of iterators produced by the iterator() method in SetOfIntegers.

import java.util.Iterator;

/* This class includes utility methods pertaining to instances 
** of the SetOfIntegers class.
*/
public class SetOfIntUtils {

   /* Returns the cardinality (i.e., number of members) 
   ** of the given set of integers.
   */
   public static int cardinality(SetOfIntegers s) {
      // Establish an iterator over set s (and a counter).
      Iterator<Integer> iter = s.iterator();
      int card = 0;

      // Iterate through the elements of set s and count them.
      while (iter.hasNext()) {
         iter.next();      // call next(), but ignore the result
         card = card + 1;  // as it is irrelevant
      }
      return card;
   }

   /* Returns the maximum element in the given set of integers.
   ** pre: cardinality(s) != 0
   */
   public static int maximum(SetOfIntegers s) {
      // Establish an iterator over set s.
      Iterator<Integer> iter = s.iterator();

      // Establish the "first" element of s as 
      // being the maximum one observed so far.
      int maxSoFar = iter.next();

      // Iterate through the elements of set s while
      // recalling the maximum one observed so far.
      while (iter.hasNext()) {
         int elem = iter.next();
         if (elem > maxSoFar) {
            maxSoFar = elem;
         }
      }
      return maxSoFar;
   }

   // more methods ...

}