    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 * The iterator implements a {@link #reset} method, allowing the reset of the iterator
    030 * back to the start if required.
    031 *
    032 * @param <E> the type to iterate over
    033 * @since 3.0
    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    @Override
    111    public boolean hasNext() {
    112        return this.index < this.endIndex;
    113    }
    114
    115    /**
    116     * Returns the next element in the array.
    117     *
    118     * @return the next element in the array
    119     * @throws NoSuchElementException if all the elements in the array
    120     *    have already been returned
    121     */
    122    @Override
    123    public E next() {
    124        if (hasNext() == false) {
    125            throw new NoSuchElementException();
    126        }
    127        return this.array[this.index++];
    128    }
    129
    130    /**
    131     * Throws {@link UnsupportedOperationException}.
    132     *
    133     * @throws UnsupportedOperationException always
    134     */
    135    @Override
    136    public void remove() {
    137        throw new UnsupportedOperationException("remove() method is not supported for an ObjectArrayIterator");
    138    }
    139
    140    // Properties
    141    //-------------------------------------------------------------------------
    142
    143    /**
    144     * Gets the array that this iterator is iterating over.
    145     *
    146     * @return the array this iterator iterates over
    147     */
    148    public E[] getArray() {
    149        return this.array;
    150    }
    151
    152    /**
    153     * Gets the start index to loop from.
    154     *
    155     * @return the start index
    156     */
    157    public int getStartIndex() {
    158        return this.startIndex;
    159    }
    160
    161    /**
    162     * Gets the end index to loop to.
    163     *
    164     * @return the end index
    165     */
    166    public int getEndIndex() {
    167        return this.endIndex;
    168    }
    169
    170    /**
    171     * Resets the iterator back to the start index.
    172     */
    173    @Override
    174    public void reset() {
    175        this.index = this.startIndex;
    176    }
    177
    178}