001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      https://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.collections4.iterators;
018
019import java.util.Iterator;
020import java.util.NoSuchElementException;
021
022import org.apache.commons.collections4.ResettableIterator;
023
024/**
025 * An {@link Iterator Iterator} over an array of objects.
026 * <p>
027 * This iterator does not support {@link #remove}, as the object array cannot be
028 * structurally modified.
029 * </p>
030 * <p>
031 * The iterator implements a {@link #reset} method, allowing the reset of the iterator
032 * back to the start if required.
033 * </p>
034 *
035 * @param <E> The type of elements returned by this iterator.
036 * @since 3.0
037 */
038public class ObjectArrayIterator<E> implements ResettableIterator<E> {
039
040    /** The array */
041    final E[] array;
042
043    /** The start index to loop from */
044    final int startIndex;
045
046    /** The end index to loop to */
047    final int endIndex;
048
049    /** The current iterator index */
050    int index;
051
052    /**
053     * Constructs an ObjectArrayIterator that will iterate over the values in the
054     * specified array.
055     *
056     * @param array The array to iterate over
057     * @throws NullPointerException if {@code array} is {@code null}
058     */
059    public ObjectArrayIterator(final E... array) {
060        this(array, 0, array.length);
061    }
062
063    /**
064     * Constructs an ObjectArrayIterator that will iterate over the values in the
065     * specified array from a specific start index.
066     *
067     * @param array  The array to iterate over
068     * @param start  The index to start iterating at
069     * @throws NullPointerException if {@code array} is {@code null}
070     * @throws IndexOutOfBoundsException if the start index is out of bounds
071     */
072    public ObjectArrayIterator(final E[] array, final int start) {
073        this(array, start, array.length);
074    }
075
076    /**
077     * Constructs an ObjectArrayIterator that will iterate over a range of values
078     * in the specified array.
079     *
080     * @param array  The array to iterate over
081     * @param start  The index to start iterating at
082     * @param end  The index (exclusive) to finish iterating at
083     * @throws IndexOutOfBoundsException if the start or end index is out of bounds
084     * @throws IllegalArgumentException if end index is before the start
085     * @throws NullPointerException if {@code array} is {@code null}
086     */
087    public ObjectArrayIterator(final E[] array, final int start, final int end) {
088        if (start < 0) {
089            throw new ArrayIndexOutOfBoundsException("Start index must not be less than zero");
090        }
091        if (end > array.length) {
092            throw new ArrayIndexOutOfBoundsException("End index must not be greater than the array length");
093        }
094        if (start > array.length) {
095            throw new ArrayIndexOutOfBoundsException("Start index must not be greater than the array length");
096        }
097        if (end < start) {
098            throw new IllegalArgumentException("End index must not be less than start index");
099        }
100        this.array = array;
101        startIndex = start;
102        endIndex = end;
103        index = start;
104    }
105
106    /**
107     * Gets the array that this iterator is iterating over.
108     *
109     * @return The array this iterator iterates over
110     */
111    public E[] getArray() {
112        return array;
113    }
114
115    /**
116     * Gets the end index to loop to.
117     *
118     * @return The end index
119     */
120    public int getEndIndex() {
121        return endIndex;
122    }
123
124    /**
125     * Gets the start index to loop from.
126     *
127     * @return The start index
128     */
129    public int getStartIndex() {
130        return startIndex;
131    }
132
133    /**
134     * Returns true if there are more elements to return from the array.
135     *
136     * @return true if there is a next element to return
137     */
138    @Override
139    public boolean hasNext() {
140        return index < endIndex;
141    }
142
143    /**
144     * Returns the next element in the array.
145     *
146     * @return The next element in the array
147     * @throws NoSuchElementException if all the elements in the array
148     *    have already been returned
149     */
150    @Override
151    public E next() {
152        if (!hasNext()) {
153            throw new NoSuchElementException();
154        }
155        return array[index++];
156    }
157
158    /**
159     * Always throws {@link UnsupportedOperationException}.
160     *
161     * @throws UnsupportedOperationException Always thrown.
162     */
163    @Override
164    public void remove() {
165        throw new UnsupportedOperationException("remove() method is not supported for an ObjectArrayIterator");
166    }
167
168    /**
169     * Resets the iterator back to the start index.
170     */
171    @Override
172    public void reset() {
173        index = startIndex;
174    }
175
176}