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 *      http://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.NoSuchElementException;
020
021import org.apache.commons.collections4.ResettableIterator;
022
023/**
024 * An {@link Iterator} over an array of objects.
025 * <p>
026 * This iterator does not support {@link #remove}, as the object array cannot be
027 * structurally modified.
028 * <p>
029 * The iterator implements a {@link #reset} method, allowing the reset of the iterator
030 * back to the start if required.
031 *
032 * @since 3.0
033 * @version $Id: ObjectArrayIterator.html 972421 2015-11-14 20:00:04Z tn $
034 */
035public class ObjectArrayIterator<E> implements ResettableIterator<E> {
036
037    /** The array */
038    final E[] array;
039    /** The start index to loop from */
040    final int startIndex;
041    /** The end index to loop to */
042    final int endIndex;
043    /** The current iterator index */
044    int index = 0;
045
046    //-------------------------------------------------------------------------
047    /**
048     * Constructs an ObjectArrayIterator that will iterate over the values in the
049     * specified array.
050     *
051     * @param array the array to iterate over
052     * @throws NullPointerException if <code>array</code> is <code>null</code>
053     */
054    public ObjectArrayIterator(final E... array) {
055        this(array, 0, array.length);
056    }
057
058    /**
059     * Constructs an ObjectArrayIterator that will iterate over the values in the
060     * specified array from a specific start index.
061     *
062     * @param array  the array to iterate over
063     * @param start  the index to start iterating at
064     * @throws NullPointerException if <code>array</code> is <code>null</code>
065     * @throws IndexOutOfBoundsException if the start index is out of bounds
066     */
067    public ObjectArrayIterator(final E array[], final int start) {
068        this(array, start, array.length);
069    }
070
071    /**
072     * Construct an ObjectArrayIterator that will iterate over a range of values
073     * in the specified array.
074     *
075     * @param array  the array to iterate over
076     * @param start  the index to start iterating at
077     * @param end  the index (exclusive) to finish iterating at
078     * @throws IndexOutOfBoundsException if the start or end index is out of bounds
079     * @throws IllegalArgumentException if end index is before the start
080     * @throws NullPointerException if <code>array</code> is <code>null</code>
081     */
082    public ObjectArrayIterator(final E array[], final int start, final int end) {
083        super();
084        if (start < 0) {
085            throw new ArrayIndexOutOfBoundsException("Start index must not be less than zero");
086        }
087        if (end > array.length) {
088            throw new ArrayIndexOutOfBoundsException("End index must not be greater than the array length");
089        }
090        if (start > array.length) {
091            throw new ArrayIndexOutOfBoundsException("Start index must not be greater than the array length");
092        }
093        if (end < start) {
094            throw new IllegalArgumentException("End index must not be less than start index");
095        }
096        this.array = array;
097        this.startIndex = start;
098        this.endIndex = end;
099        this.index = start;
100    }
101
102    // Iterator interface
103    //-------------------------------------------------------------------------
104
105    /**
106     * Returns true if there are more elements to return from the array.
107     *
108     * @return true if there is a next element to return
109     */
110    public boolean hasNext() {
111        return this.index < this.endIndex;
112    }
113
114    /**
115     * Returns the next element in the array.
116     *
117     * @return the next element in the array
118     * @throws NoSuchElementException if all the elements in the array
119     *    have already been returned
120     */
121    public E next() {
122        if (hasNext() == false) {
123            throw new NoSuchElementException();
124        }
125        return this.array[this.index++];
126    }
127
128    /**
129     * Throws {@link UnsupportedOperationException}.
130     *
131     * @throws UnsupportedOperationException always
132     */
133    public void remove() {
134        throw new UnsupportedOperationException("remove() method is not supported for an ObjectArrayIterator");
135    }
136
137    // Properties
138    //-------------------------------------------------------------------------
139
140    /**
141     * Gets the array that this iterator is iterating over.
142     *
143     * @return the array this iterator iterates over
144     */
145    public E[] getArray() {
146        return this.array;
147    }
148
149    /**
150     * Gets the start index to loop from.
151     *
152     * @return the start index
153     */
154    public int getStartIndex() {
155        return this.startIndex;
156    }
157
158    /**
159     * Gets the end index to loop to.
160     *
161     * @return the end index
162     */
163    public int getEndIndex() {
164        return this.endIndex;
165    }
166
167    /**
168     * Resets the iterator back to the start index.
169     */
170    public void reset() {
171        this.index = this.startIndex;
172    }
173
174}