Java Cookbook, Second Edition

Problem

You have your own data structure, but you want to publish the data as an Iterator to provide generic access to it.

Solution

You need to write your own Iterator. Just implement (or provide an inner class that implements) the Iterator (or Enumeration ) interface.

Discussion

To make data from one part of your program available in a storage-independent way to other parts of the code, generate an Iterator. Here is a short program that constructs, upon request, an Iterator for some data that it is storing in this case, in an array. The Iterator interface has only three methods: hasNext( ) , next( ), and remove( ):

package com.darwinsys.util; import java.util.Iterator; /** De-mystify the Iterator interface, showing how * to write a simple Iterator for an Array of Objects. * @author Ian Darwin, http://www.darwinsys.com/ * @version $Id: ch07.xml,v 1.5 2004/05/04 20:11:49 ian Exp $ */ public class ArrayIterator implements Iterator { /** The data to be iterated over. */ protected Object[] data; protected int index = 0; /** Construct an ArrayIterator object. * @param data The array of objects to be iterated over. */ public ArrayIterator(Object[] data) { setData(data); } /** (Re)set the data array to the given array, and reset the iterator. * @param data The array of objects to be iterated over. */ public void setData(Object[] data) { this.data = data; index = 0; } /** * Tell if there are any more elements. * @return true if not at the end, i.e., if next( ) will succeed. * @return false if next( ) will throw an exception. */ public boolean hasNext( ) { return (index < data.length); } /** Returns the next element from the data */ public Object next( ) { if (hasNext( )) { return data[index++]; } throw new IndexOutOfBoundsException("only " + data.length + " elements"); } /** Remove the object that next( ) just returned. * An Iterator is not required to support this interface, * and we certainly don't! */ public void remove( ) { throw new UnsupportedOperationException( "This demo does not implement the remove method"); } /** Simple tryout */ protected String[] data = { "one", "two", "three" }; public static void main(String unused[]) { ArrayIterator it = new ArrayIterator(data ); while (it.hasNext( )) System.out.println(it.next( )); } }

The comments above the remove( ) method remind me of an interesting point. This interface introduces something new to Java, the optional method . Since there is no syntax for this, and they didn't want to introduce any new syntax, the developers of the Collections Framework decided on an implementation using existing syntax. If they are not implemented, the optional methods are required to throw an UnsupportedOperationException if they ever get called. My remove( ) method does this. Note that UnsupportedOperationException is subclassed from RunTimeException, so it is not required to be declared or caught.

This code is unrealistic in several ways, but it does show the syntax and how the Iterator interface works. In real code, the Iterator and the data are usually separate objects (the Iterator might be an inner class from the data store class). Also, you don't even need to write this code for an array; you can just construct an ArrayList object, copy the array elements into it, and ask it to provide the Iterator. However, I believe it's worth showing this simple example of the internals of an Iterator so that you can understand both how it works and how you could provide one for a more sophisticated data structure, should the need arise.

Категории