    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 java.util.Iterator 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 * <p>
    030 * The iterator implements a {@link #reset} method, allowing the reset of the iterator
    031 * back to the start if required.
    032 * </p>
    033 *
    034 * @param <E> the type of elements returned by this iterator.
    035 * @since 3.0
    036 */
    037public class ObjectArrayIterator<E> implements ResettableIterator<E> {
    038
    039    /** The array */
    040    final E[] array;
    041    /** The start index to loop from */
    042    final int startIndex;
    043    /** The end index to loop to */
    044    final int endIndex;
    045    /** The current iterator index */
    046    int index;
    047
    048    /**
    049     * Constructs an ObjectArrayIterator that will iterate over the values in the
    050     * specified array.
    051     *
    052     * @param array the array to iterate over
    053     * @throws NullPointerException if {@code array} is {@code null}
    054     */
    055    public ObjectArrayIterator(final E... array) {
    056        this(array, 0, array.length);
    057    }
    058
    059    /**
    060     * Constructs an ObjectArrayIterator that will iterate over the values in the
    061     * specified array from a specific start index.
    062     *
    063     * @param array  the array to iterate over
    064     * @param start  the index to start iterating at
    065     * @throws NullPointerException if {@code array} is {@code null}
    066     * @throws IndexOutOfBoundsException if the start index is out of bounds
    067     */
    068    public ObjectArrayIterator(final E[] array, final int start) {
    069        this(array, start, array.length);
    070    }
    071
    072    /**
    073     * Constructs an ObjectArrayIterator that will iterate over a range of values
    074     * in the specified array.
    075     *
    076     * @param array  the array to iterate over
    077     * @param start  the index to start iterating at
    078     * @param end  the index (exclusive) to finish iterating at
    079     * @throws IndexOutOfBoundsException if the start or end index is out of bounds
    080     * @throws IllegalArgumentException if end index is before the start
    081     * @throws NullPointerException if {@code array} is {@code null}
    082     */
    083    public ObjectArrayIterator(final E[] array, final int start, final int end) {
    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        startIndex = start;
    098        endIndex = end;
    099        index = start;
    100    }
    101
    102    /**
    103     * Gets the array that this iterator is iterating over.
    104     *
    105     * @return the array this iterator iterates over
    106     */
    107    public E[] getArray() {
    108        return array;
    109    }
    110
    111    /**
    112     * Gets the end index to loop to.
    113     *
    114     * @return the end index
    115     */
    116    public int getEndIndex() {
    117        return endIndex;
    118    }
    119
    120    /**
    121     * Gets the start index to loop from.
    122     *
    123     * @return the start index
    124     */
    125    public int getStartIndex() {
    126        return startIndex;
    127    }
    128
    129    /**
    130     * Returns true if there are more elements to return from the array.
    131     *
    132     * @return true if there is a next element to return
    133     */
    134    @Override
    135    public boolean hasNext() {
    136        return index < endIndex;
    137    }
    138
    139    /**
    140     * Returns the next element in the array.
    141     *
    142     * @return the next element in the array
    143     * @throws NoSuchElementException if all the elements in the array
    144     *    have already been returned
    145     */
    146    @Override
    147    public E next() {
    148        if (!hasNext()) {
    149            throw new NoSuchElementException();
    150        }
    151        return array[index++];
    152    }
    153
    154    /**
    155     * Throws {@link UnsupportedOperationException}.
    156     *
    157     * @throws UnsupportedOperationException always
    158     */
    159    @Override
    160    public void remove() {
    161        throw new UnsupportedOperationException("remove() method is not supported for an ObjectArrayIterator");
    162    }
    163
    164    /**
    165     * Resets the iterator back to the start index.
    166     */
    167    @Override
    168    public void reset() {
    169        index = startIndex;
    170    }
    171
    172}