package util; /** * An iterator to walk through arrays (or array subsets) in left-to-right or * right-to-left order. */ public class ArrayIterator<T> extends AbstractBiIterator<T> implements Iterable<T>, Cloneable { /****************************************************************************/ private final T[] array; /****************************************************************************/ private int index; /****************************************************************************/ private final int start, end; /****************************************************************************/ private final int dir; /****************************************************************************/ public ArrayIterator(T[] array, int start, int end) { this.dir = start < end ? 1 : -1; this.array = array; this.index = start - dir; this.start = start; this.end = end; } /****************************************************************************/ public ArrayIterator(T[] array, boolean reverse) { this(array, !reverse ? 0 : array.length - 1, !reverse ? array.length : -1); } /****************************************************************************/ public ArrayIterator(T[] array) { this(array, false); } /****************************************************************************/ @Override public boolean pastEdge() { return dir * index < dir * start || dir * end <= dir * index; } /****************************************************************************/ @Override public T current() { return pastEdge() ? null : array[index]; } /****************************************************************************/ @Override public void forward() { index += dir; } /****************************************************************************/ @Override public void backward() { index -= dir; } /****************************************************************************/ @Override public boolean hasNext() { return dir * index < dir * end - 1; } /****************************************************************************/ @Override public boolean hasPrev() { return dir * start < dir * index; } /***************************************************************************** * Returns the array index of the item below the reading head, or -1 if * the head is past the edge of the sequence. */ public int index() { return pastEdge() ? -1 : index; } /***************************************************************************** * Returns the index of the item below the reading head in the sequence, or -1 * if the head is past the edge of the sequence. */ public int iterIndex() { return pastEdge() ? -1 : dir * (index - start); } /****************************************************************************/ public void replace(T replacement) { array[index] = replacement; } /****************************************************************************/ @Override public void remove() { throw new UnsupportedOperationException(); } /****************************************************************************/ @Override public ArrayIterator<T> iterator() { return this; } /****************************************************************************/ public ArrayIterator<T> newIterator() { return new ArrayIterator<>(array, start, end); } /****************************************************************************/ @SuppressWarnings("unchecked") @Override public ArrayIterator<T> clone() { try { return (ArrayIterator<T>) super.clone(); } catch (CloneNotSupportedException e) { throw new Error("unreachable error"); } } }