Implement the Iterator Pattern

Part III

It is a common practice to place the iterator class for a data structure inside the data structure class itself.

In java, it is possible to define a class within another class, such classes are known as nested (or inner) classes.

public class ArrayIndexedList<T> implements IndexedList<T> {
  private final T[] data;

  // No changes were made to other operations. 

  @Override
  public Iterator<T> iterator() {
    return new ArrayIndexedListIterator();
  }

  private class ArrayIndexedListIterator implements Iterator<T> {
    private int cursor = 0;

    @Override
    public boolean hasNext() {
      return cursor < data.length;
    }

    @Override
    public T next() {
      if (!hasNext()) {
        throw new NoSuchElementException();
      }
      return data[cursor++];
    }
  }
}

There are advantages to using an inner class:

  • It is a way of logically grouping classes that are only used in one place: If a class is useful to only one other class, then it is logical to embed it in that class and keep the two together.
  • It increases encapsulation: ArrayIndexedListIterator needs access to data member of ArrayIndexedList. By nesting ArrayIndexedListIterator within class ArrayIndexedList, it gets access to all ArrayIndexedList members (including the private ones). In addition, ArrayIndexedListIterator itself can be hidden from the outside world (simply declare it as a private member).
  • It can lead to more readable and maintainable code: Nesting small classes within top-level classes places the code closer to where it is used.

In this course, we always use an inner class to implement the Iterator interface for a data structure.

Resources