/** * An array list iterator that does not support remove (see note below) * @author Edo Biagioni * @lecture ICS 211 Feb 8 (or later) * @date February 6, 2011 */ private static class ArrayListIterator<E> implements java.util.Iterator<E> { private E[] data; private int position; // invariant: position >= 0 private int limit; // invariant: limit <= data.length private boolean nextCalled; // keep track of next() being called // invariant: if nextCalled is true, position >= 1 // this constructor takes as parameters the data over which we iterate private ArrayListIterator(E[] data, int size) { if ((data == null) || (data.length < size)) { throw new IllegalArgumentException("illegal call to constructor"); } this.data = data; limit = size; // stop before reaching limit position = 0; nextCalled = false; } public boolean hasNext() { return (position < limit); } public E next() { if (hasNext()) { nextCalled = true; // allow calling remove() E result = data[position]; position++; return result; } // no next element throw new java.util.NoSuchElementException("linked list.next"); } /* the only problem with this code for remove is that "limit" is * a class variable of this iterator. Decrementing limit records * in the iterator that the collection has gotten smaller, but does * not communicate this information to the collection object. * * fixing this code would require changing the constructor to take * as argument an object that holds an int value, and allows us to * change it, and to share that value with the Collection class. * Since this is just example, code, I have not implemented that. */ public void remove() { if (! nextCalled) { throw new IllegalStateException ("can only call after next()"); } nextCalled = false; // no more calls to remove(), until next() // invariant: if nextCalled is true, position >= 1 // item to be removed is at position-1 for (int i = position; i < limit; i++) { // O(n) loop data [i - 1] = data [i]; } limit--; // removed one element from the collection position--; // position changes as well data[limit] = null; // optional } }