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.Iterator;
20 import java.util.NoSuchElementException;
21
22 import org.apache.commons.collections.ResettableIterator;
23
24 /**
25 * An {@link Iterator} over an array of objects.
26 * <p>
27 * This iterator does not support {@link #remove}, as the object array cannot be
28 * structurally modified.
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 * @since 3.0
34 * @version $Id: ObjectArrayIterator.java 1429905 2013-01-07 17:15:14Z ggregory $
35 */
36 public class ObjectArrayIterator<E>
37 implements Iterator<E>, ResettableIterator<E> {
38
39 /** The array */
40 protected E[] array = null;
41 /** The start index to loop from */
42 protected int startIndex = 0;
43 /** The end index to loop to */
44 protected int endIndex = 0;
45 /** The current iterator index */
46 protected int index = 0;
47
48 /**
49 * Constructor for use with <code>setArray</code>.
50 * <p>
51 * Using this constructor, the iterator is equivalent to an empty iterator
52 * until {@link #setArray} is called to establish the array to iterate over.
53 */
54 public ObjectArrayIterator() {
55 super();
56 }
57
58 /**
59 * Constructs an ObjectArrayIterator that will iterate over the values in the
60 * specified array.
61 *
62 * @param array the array to iterate over
63 * @throws NullPointerException if <code>array</code> is <code>null</code>
64 */
65 public ObjectArrayIterator(final E... array) {
66 this(array, 0, array.length);
67 }
68
69 /**
70 * Constructs an ObjectArrayIterator that will iterate over the values in the
71 * specified array from a specific start index.
72 *
73 * @param array the array to iterate over
74 * @param start the index to start iterating at
75 * @throws NullPointerException if <code>array</code> is <code>null</code>
76 * @throws IndexOutOfBoundsException if the start index is out of bounds
77 */
78 public ObjectArrayIterator(final E array[], final int start) {
79 this(array, start, array.length);
80 }
81
82 /**
83 * Construct an ObjectArrayIterator that will iterate over a range of values
84 * in the specified array.
85 *
86 * @param array the array to iterate over
87 * @param start the index to start iterating at
88 * @param end the index (exclusive) to finish iterating at
89 * @throws IndexOutOfBoundsException if the start or end index is out of bounds
90 * @throws IllegalArgumentException if end index is before the start
91 * @throws NullPointerException if <code>array</code> is <code>null</code>
92 */
93 public ObjectArrayIterator(final E array[], final int start, final int end) {
94 super();
95 if (start < 0) {
96 throw new ArrayIndexOutOfBoundsException("Start index must not be less than zero");
97 }
98 if (end > array.length) {
99 throw new ArrayIndexOutOfBoundsException("End index must not be greater than the array length");
100 }
101 if (start > array.length) {
102 throw new ArrayIndexOutOfBoundsException("Start index must not be greater than the array length");
103 }
104 if (end < start) {
105 throw new IllegalArgumentException("End index must not be less than start index");
106 }
107 this.array = array;
108 this.startIndex = start;
109 this.endIndex = end;
110 this.index = start;
111 }
112
113 // Iterator interface
114 //-------------------------------------------------------------------------
115
116 /**
117 * Returns true if there are more elements to return from the array.
118 *
119 * @return true if there is a next element to return
120 */
121 public boolean hasNext() {
122 return this.index < this.endIndex;
123 }
124
125 /**
126 * Returns the next element in the array.
127 *
128 * @return the next element in the array
129 * @throws NoSuchElementException if all the elements in the array
130 * have already been returned
131 */
132 public E next() {
133 if (hasNext() == false) {
134 throw new NoSuchElementException();
135 }
136 return this.array[this.index++];
137 }
138
139 /**
140 * Throws {@link UnsupportedOperationException}.
141 *
142 * @throws UnsupportedOperationException always
143 */
144 public void remove() {
145 throw new UnsupportedOperationException("remove() method is not supported for an ObjectArrayIterator");
146 }
147
148 // Properties
149 //-------------------------------------------------------------------------
150
151 /**
152 * Gets the array that this iterator is iterating over.
153 *
154 * @return the array this iterator iterates over, or <code>null</code> if
155 * the no-arg constructor was used and {@link #setArray} has never
156 * been called with a valid array.
157 */
158 public E[] getArray() {
159 return this.array;
160 }
161
162 /**
163 * Sets the array that the ArrayIterator should iterate over.
164 * <p>
165 * This method may only be called once, otherwise an IllegalStateException
166 * will occur.
167 * <p>
168 * The {@link #reset} method can be used to reset the iterator if required.
169 *
170 * @param array the array that the iterator should iterate over
171 * @throws IllegalStateException if the <code>array</code> was set in the constructor
172 * @throws NullPointerException if <code>array</code> is <code>null</code>
173 */
174 public void setArray(final E[] array) {
175 if (this.array != null) {
176 throw new IllegalStateException("The array to iterate over has already been set");
177 }
178 this.array = array;
179 this.startIndex = 0;
180 this.endIndex = array.length;
181 this.index = 0;
182 }
183
184 /**
185 * Gets the start index to loop from.
186 *
187 * @return the start index
188 */
189 public int getStartIndex() {
190 return this.startIndex;
191 }
192
193 /**
194 * Gets the end index to loop to.
195 *
196 * @return the end index
197 */
198 public int getEndIndex() {
199 return this.endIndex;
200 }
201
202 /**
203 * Resets the iterator back to the start index.
204 */
205 public void reset() {
206 this.index = this.startIndex;
207 }
208
209 }