1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.collections.iterators;
18
19 import java.util.ListIterator;
20 import java.util.NoSuchElementException;
21
22 import org.apache.commons.collections.ResettableListIterator;
23
24 /**
25 * Implements a {@link ListIterator} over an array of objects.
26 * <p>
27 * This iterator does not support {@link #add} or {@link #remove}, as the object array
28 * cannot be structurally modified. The {@link #set} method is supported however.
29 * <p>
30 * The iterator implements a {@link #reset} method, allowing the reset of the iterator
31 * back to the start if required.
32 *
33 * @see org.apache.commons.collections.iterators.ObjectArrayIterator
34 * @see java.util.Iterator
35 * @see java.util.ListIterator
36 *
37 * @since 3.0
38 * @version $Id: ObjectArrayListIterator.java 1429905 2013-01-07 17:15:14Z ggregory $
39 */
40 public class ObjectArrayListIterator<E> extends ObjectArrayIterator<E>
41 implements ListIterator<E>, ResettableListIterator<E> {
42
43 /**
44 * Holds the index of the last item returned by a call to <code>next()</code>
45 * or <code>previous()</code>. This is set to <code>-1</code> if neither method
46 * has yet been invoked. <code>lastItemIndex</code> is used to to implement the
47 * {@link #set} method.
48 */
49 protected int lastItemIndex = -1;
50
51 /**
52 * Constructor for use with <code>setArray</code>.
53 * <p>
54 * Using this constructor, the iterator is equivalent to an empty iterator
55 * until {@link #setArray} is called to establish the array to iterate over.
56 */
57 public ObjectArrayListIterator() {
58 super();
59 }
60
61 /**
62 * Constructs an ObjectArrayListIterator that will iterate over the values in the
63 * specified array.
64 *
65 * @param array the array to iterate over
66 * @throws NullPointerException if <code>array</code> is <code>null</code>
67 */
68 public ObjectArrayListIterator(final E... array) {
69 super(array);
70 }
71
72 /**
73 * Constructs an ObjectArrayListIterator that will iterate over the values in the
74 * specified array from a specific start index.
75 *
76 * @param array the array to iterate over
77 * @param start the index to start iterating at
78 * @throws NullPointerException if <code>array</code> is <code>null</code>
79 * @throws IndexOutOfBoundsException if the start index is out of bounds
80 */
81 public ObjectArrayListIterator(final E[] array, final int start) {
82 super(array, start);
83 }
84
85 /**
86 * Construct an ObjectArrayListIterator that will iterate over a range of values
87 * in the specified array.
88 *
89 * @param array the array to iterate over
90 * @param start the index to start iterating at
91 * @param end the index (exclusive) to finish iterating at
92 * @throws IndexOutOfBoundsException if the start or end index is out of bounds
93 * @throws IllegalArgumentException if end index is before the start
94 * @throws NullPointerException if <code>array</code> is <code>null</code>
95 */
96 public ObjectArrayListIterator(final E[] array, final int start, final int end) {
97 super(array, start, end);
98 }
99
100 // ListIterator interface
101 //-------------------------------------------------------------------------
102
103 /**
104 * Returns true if there are previous elements to return from the array.
105 *
106 * @return true if there is a previous element to return
107 */
108 public boolean hasPrevious() {
109 return this.index > this.startIndex;
110 }
111
112 /**
113 * Gets the previous element from the array.
114 *
115 * @return the previous element
116 * @throws NoSuchElementException if there is no previous element
117 */
118 public E previous() {
119 if (hasPrevious() == false) {
120 throw new NoSuchElementException();
121 }
122 this.lastItemIndex = --this.index;
123 return this.array[this.index];
124 }
125
126 /**
127 * Gets the next element from the array.
128 *
129 * @return the next element
130 * @throws NoSuchElementException if there is no next element
131 */
132 @Override
133 public E next() {
134 if (hasNext() == false) {
135 throw new NoSuchElementException();
136 }
137 this.lastItemIndex = this.index;
138 return this.array[this.index++];
139 }
140
141 /**
142 * Gets the next index to be retrieved.
143 *
144 * @return the index of the item to be retrieved next
145 */
146 public int nextIndex() {
147 return this.index - this.startIndex;
148 }
149
150 /**
151 * Gets the index of the item to be retrieved if {@link #previous()} is called.
152 *
153 * @return the index of the item to be retrieved next
154 */
155 public int previousIndex() {
156 return this.index - this.startIndex - 1;
157 }
158
159 /**
160 * This iterator does not support modification of its backing array's size, and so will
161 * always throw an {@link UnsupportedOperationException} when this method is invoked.
162 *
163 * @param obj the object to add
164 * @throws UnsupportedOperationException always thrown.
165 */
166 public void add(final E obj) {
167 throw new UnsupportedOperationException("add() method is not supported");
168 }
169
170 /**
171 * Sets the element under the cursor.
172 * <p>
173 * This method sets the element that was returned by the last call
174 * to {@link #next()} of {@link #previous()}.
175 *
176 * <b>Note:</b> {@link ListIterator} implementations that support <code>add()</code>
177 * and <code>remove()</code> only allow <code>set()</code> to be called once per call
178 * to <code>next()</code> or <code>previous</code> (see the {@link ListIterator}
179 * javadoc for more details). Since this implementation does not support
180 * <code>add()</code> or <code>remove()</code>, <code>set()</code> may be
181 * called as often as desired.
182 *
183 * @param obj the object to set into the array
184 * @throws IllegalStateException if next() has not yet been called.
185 * @throws ClassCastException if the object type is unsuitable for the array
186 */
187 public void set(final E obj) {
188 if (this.lastItemIndex == -1) {
189 throw new IllegalStateException("must call next() or previous() before a call to set()");
190 }
191
192 this.array[this.lastItemIndex] = obj;
193 }
194
195 /**
196 * Resets the iterator back to the start index.
197 */
198 @Override
199 public void reset() {
200 super.reset();
201 this.lastItemIndex = -1;
202 }
203
204 }