Implement the Iterator Pattern

Part II

Here is an implementation for hasNext and next methods:

public class ArrayIndexedListIterator<T> implements Iterator<T> {
  private T[] data;
  private int cursor;

  public ArrayIndexedListIterator(T[] data) {
    this.data = data;
    this.cursor = 0;
  }

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

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

Notes:

  • We need a way to point to the data (elements) stored in the data structure we want to iterate over (the ArrayIndexedList here). In the implementation provided here, we store a reference (data) which is initialized by the constructor.
  • We need to keep track of the current element. This is done using the cursor. In our implementation, the cursor is simply the index position but this generally depends on the underlying implementation of the data structure which the iterator is for.
  • hasNext is true if the cursor has not reached the last element.
  • next returns the current element pointed by the cursor and advances the cursor.
  • next should throw NoSuchElementException when a client calls it after the iteration is over.

Now, update the implementation of ArrayIndexedList.iterator to use ArrayIndexedListIterator:

public class ArrayIndexedList<T> implements IndexedList<T> {

  // No changes were made to other operations.

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

Run the tests and make sure they all pass!