001: /*
002: * Copyright 1999-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.collections.iterators;
017:
018: import java.lang.reflect.Array;
019: import java.util.ListIterator;
020: import java.util.NoSuchElementException;
021:
022: import org.apache.commons.collections.ResettableListIterator;
023:
024: /**
025: * Implements a {@link ListIterator} over an array.
026: * <p>
027: * The array can be either an array of object or of primitives. If you know
028: * that you have an object array, the {@link ObjectArrayListIterator}
029: * class is a better choice, as it will perform better.
030: *
031: * <p>
032: * This iterator does not support {@link #add(Object)} or {@link #remove()}, as the array
033: * cannot be changed in size. The {@link #set(Object)} method is supported however.
034: *
035: * @see org.apache.commons.collections.iterators.ArrayIterator
036: * @see java.util.Iterator
037: * @see java.util.ListIterator
038: *
039: * @since Commons Collections 3.0
040: * @version $Revision: 155406 $ $Date: 2005-02-26 12:55:26 +0000 (Sat, 26 Feb 2005) $
041: *
042: * @author Neil O'Toole
043: * @author Stephen Colebourne
044: * @author Phil Steitz
045: */
046: public class ArrayListIterator extends ArrayIterator implements
047: ListIterator, ResettableListIterator {
048:
049: /**
050: * Holds the index of the last item returned by a call to <code>next()</code>
051: * or <code>previous()</code>. This is set to <code>-1</code> if neither method
052: * has yet been invoked. <code>lastItemIndex</code> is used to to implement
053: * the {@link #set} method.
054: *
055: */
056: protected int lastItemIndex = -1;
057:
058: // Constructors
059: // ----------------------------------------------------------------------
060: /**
061: * Constructor for use with <code>setArray</code>.
062: * <p>
063: * Using this constructor, the iterator is equivalent to an empty iterator
064: * until {@link #setArray(Object)} is called to establish the array to iterate over.
065: */
066: public ArrayListIterator() {
067: super ();
068: }
069:
070: /**
071: * Constructs an ArrayListIterator that will iterate over the values in the
072: * specified array.
073: *
074: * @param array the array to iterate over
075: * @throws IllegalArgumentException if <code>array</code> is not an array.
076: * @throws NullPointerException if <code>array</code> is <code>null</code>
077: */
078: public ArrayListIterator(Object array) {
079: super (array);
080: }
081:
082: /**
083: * Constructs an ArrayListIterator that will iterate over the values in the
084: * specified array from a specific start index.
085: *
086: * @param array the array to iterate over
087: * @param startIndex the index to start iterating at
088: * @throws IllegalArgumentException if <code>array</code> is not an array.
089: * @throws NullPointerException if <code>array</code> is <code>null</code>
090: * @throws IndexOutOfBoundsException if the start index is out of bounds
091: */
092: public ArrayListIterator(Object array, int startIndex) {
093: super (array, startIndex);
094: this .startIndex = startIndex;
095: }
096:
097: /**
098: * Construct an ArrayListIterator that will iterate over a range of values
099: * in the specified array.
100: *
101: * @param array the array to iterate over
102: * @param startIndex the index to start iterating at
103: * @param endIndex the index (exclusive) to finish iterating at
104: * @throws IllegalArgumentException if <code>array</code> is not an array.
105: * @throws IndexOutOfBoundsException if the start or end index is out of bounds
106: * @throws IllegalArgumentException if end index is before the start
107: * @throws NullPointerException if <code>array</code> is <code>null</code>
108: */
109: public ArrayListIterator(Object array, int startIndex, int endIndex) {
110: super (array, startIndex, endIndex);
111: this .startIndex = startIndex;
112: }
113:
114: // ListIterator interface
115: //-----------------------------------------------------------------------
116: /**
117: * Returns true if there are previous elements to return from the array.
118: *
119: * @return true if there is a previous element to return
120: */
121: public boolean hasPrevious() {
122: return (this .index > this .startIndex);
123: }
124:
125: /**
126: * Gets the previous element from the array.
127: *
128: * @return the previous element
129: * @throws NoSuchElementException if there is no previous element
130: */
131: public Object previous() {
132: if (hasPrevious() == false) {
133: throw new NoSuchElementException();
134: }
135: this .lastItemIndex = --this .index;
136: return Array.get(this .array, this .index);
137: }
138:
139: /**
140: * Gets the next element from the array.
141: *
142: * @return the next element
143: * @throws NoSuchElementException if there is no next element
144: */
145: public Object next() {
146: if (hasNext() == false) {
147: throw new NoSuchElementException();
148: }
149: this .lastItemIndex = this .index;
150: return Array.get(this .array, this .index++);
151: }
152:
153: /**
154: * Gets the next index to be retrieved.
155: *
156: * @return the index of the item to be retrieved next
157: */
158: public int nextIndex() {
159: return this .index - this .startIndex;
160: }
161:
162: /**
163: * Gets the index of the item to be retrieved if {@link #previous()} is called.
164: *
165: * @return the index of the item to be retrieved next
166: */
167: public int previousIndex() {
168: return this .index - this .startIndex - 1;
169: }
170:
171: /**
172: * This iterator does not support modification of its backing collection, and so will
173: * always throw an {@link UnsupportedOperationException} when this method is invoked.
174: *
175: * @throws UnsupportedOperationException always thrown.
176: * @see java.util.ListIterator#set
177: */
178: public void add(Object o) {
179: throw new UnsupportedOperationException(
180: "add() method is not supported");
181: }
182:
183: /**
184: * Sets the element under the cursor.
185: * <p>
186: * This method sets the element that was returned by the last call
187: * to {@link #next()} of {@link #previous()}.
188: * <p>
189: * <b>Note:</b> {@link ListIterator} implementations that support
190: * <code>add()</code> and <code>remove()</code> only allow <code>set()</code> to be called
191: * once per call to <code>next()</code> or <code>previous</code> (see the {@link ListIterator}
192: * javadoc for more details). Since this implementation does
193: * not support <code>add()</code> or <code>remove()</code>, <code>set()</code> may be
194: * called as often as desired.
195: *
196: * @see java.util.ListIterator#set
197: */
198: public void set(Object o) {
199: if (this .lastItemIndex == -1) {
200: throw new IllegalStateException(
201: "must call next() or previous() before a call to set()");
202: }
203:
204: Array.set(this .array, this .lastItemIndex, o);
205: }
206:
207: /**
208: * Resets the iterator back to the start index.
209: */
210: public void reset() {
211: super .reset();
212: this .lastItemIndex = -1;
213: }
214:
215: }
|