Iterators.java Source code

Java tutorial

Introduction

Here is the source code for Iterators.java

Source

/*
 * LingPipe v. 3.9
 * Copyright (C) 2003-2010 Alias-i
 *
 * This program is licensed under the Alias-i Royalty Free License
 * Version 1 WITHOUT ANY WARRANTY, without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the Alias-i
 * Royalty Free License Version 1 for more details.
 *
 * You should have received a copy of the Alias-i Royalty Free License
 * Version 1 along with this program; if not, visit
 * http://alias-i.com/lingpipe/licenses/lingpipe-license-1.txt or contact
 * Alias-i, Inc. at 181 North 11th Street, Suite 401, Brooklyn, NY 11211,
 * +1 (718) 290-9170.
 */

//package com.aliasi.util;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.List;

/**
 * Static utility methods, classes, and abstract classes for
 * iteration.
 *
 * @author  Bob Carpenter
 * @author  Mike Ross
 * @version 4.0.0
 * @since   LingPipe2.0
 */
public class Iterators {

    // do not allow instances
    private Iterators() {
        /* no instances */
    }

    static final Iterator<Object> EMPTY_ITERATOR = new Empty<Object>();

    /**
     * Returns an iterator that has no elements.  Thus {@code
     * hasNext()} will always return {@code false} and {@code next()}
     * will always throw a {@code NoSuchElementException}.
     *
     * @return The empty iterator.
     */
    public static <E> Iterator<E> empty() {
        @SuppressWarnings("unchecked")
        Iterator<E> emptyIterator = (Iterator<E>) EMPTY_ITERATOR;
        return emptyIterator;
    }

    /**
     * Returns an iterator over the single specified element.
     * Thus {@code next()} will return the specified element
     * on the first call, with subsequent calls
     * throwing a {@code NoSuchElementException}  .
     *
     * @param e The object to return in the iterator.
     * @return The iterator over the specified object.
     */
    public static <E> Iterator<E> singleton(E e) {
        Iterator<E> singletonIterator = new Singleton<E>(e);
        return singletonIterator;
    }

    /**
     * Returns a newly constructed iterator over the specified pair of
     * elements.
     *
     * <p><i>Implementation Note:</i> References to the elemenets are
     * removed from iterator after they are returned through {@code
     * next()}.
     *
     * @param e1 First element returned.
     * @param e2 Second element returned.
     * @return The iterator over the pair of elements specified.
     */
    public static <E> Iterator<E> pair(E e1, E e2) {
        return new Pair<E>(e1, e2);
    }

    /**
     * Returns an iterator constructed from the specified variable
     * length argument list of objects.  
     *
     * <p>Remove is supported, but has no effect on anything as the
     * list from which elements are being deleted is only used for the
     * iterator.
     *
     * @param es Array of objects for iteration.
     * @return Iterator over list.
     */
    public static <E> Iterator<E> list(E... es) {
        return java.util.Arrays.<E>asList(es).iterator();
    }

    /**
     * Returns an unmodifiable view of the specified iterator.
     * Calls to {@code next()} and {@code hasNext()} are delegated
     * to the specified iterator as made.  Calls to {@code remove()}
     * throw unsupported operation exceptions.
     *
     * @param it Iterator to view.
     * @return Unmodifiable view of specified iterator.
     */
    public static <E> Iterator<E> unmodifiable(Iterator<E> it) {
        final Iterator<E> mIt = it;
        return new Iterator<E>() {
            public boolean hasNext() {
                return mIt.hasNext();
            }

            public E next() {
                return mIt.next();
            }

            public void remove() {
                String msg = "Cannot remove from an unmodifiable iterator.";
                throw new UnsupportedOperationException(msg);
            }
        };
    }

    /**
     * Returns an iterator that runs through the first iterator's
     * elements and then runs through the second iterator's elements.
     *
     * <p>References to the iterators are freed after it is finished
     * iterating.
     *
     * @param it1 The first iterator in the sequence.
     * @param it2 The second iterator in the sequence.
     * @return The iterator over the two iterators.
     */
    public static <E> Iterator<E> sequence(Iterator<? extends E> it1, Iterator<? extends E> it2) {
        Iterator<E> result = new Sequence<E>(it1, it2);
        return result;
    }

    public static <E> Iterator<E> sequence(List<? extends Iterator<? extends E>> iterators) {
        @SuppressWarnings({ "unchecked", "rawtypes" })
        Iterator<? extends E>[] elts = (Iterator<? extends E>[]) iterators.toArray(new Iterator[0]);
        Iterator<E> it = new Sequence<E>(elts);
        return it;
    }

    public static <E> Iterator<E> sequence(Iterator<? extends Iterator<? extends E>> iteratorOfIterators) {

        Iterator<E> it = new Sequence<E>(iteratorOfIterators);
        return it;
    }

    /**
     * Returns an iterator over the specified array of objects.
     *
     * <p><i>Warning:</i> The array is not copied, so any changes in
     * the underlying array are reflected in the iterator.
     *
     * <P><I>Implementation Note:</I> this class does not
     * automatically free references in the underlying array, because
     * the array may be used elswhere.  If reference freeing is
     * critical here, a call to {@code remove()} after ever call to
     * {@code next()} will free the references in the array.
     *
     * @param members Array of elements over which to iterate.
     * @return The iterator over the array elements.
     */
    public static <E> Iterator<E> array(E[] members) {
        return new Array<E>(members);
    }

    /**
     * Returns a newly constructed iterator over the specified
     * object array slice.
     *
     * <p>The {@code remove()} method is not supported.
     *
     * <p><i>Warning:</i> The array is not copied, so any changes in
     * the underlying array are reflected in the iterator.
     *
     * <P><I>Implementation Note:</I> this class does not
     * automatically free references in the underlying array, because
     * the array may be used elswhere.
     *
     * @param members Array of objects over which to iterate.
     * @param start Index of first object to return.
     * @param length Number of objects to iterate.
     * @throws Illegal argument exception if {@code start < 0} or
     * {@code start + length > objects.length()}.
     */
    public static <E> Iterator<E> arraySlice(E[] members, int start, int length) {
        return new ArraySlice<E>(members, start, length);
    }

    /**
     * An <code>Iterator.Array</code> iterates over the elements of an
     * array specified at construction time.
     *
     * <P><I>Implementation Note:</I> this class does not automatically
     * free references in the underlying array, because the array
     * may be used elswhere.  If reference freeing is critical here,
     * a call to <code>remove()</code> after ever <code>next()</code>
     * will free the references in the array.
     *
     * @author  Bob Carpenter
     * @version 3.8
     * @since   LingPipe1.0
     * @param <E> the type of objects returned by the iterator
     */
    static class Array<E> implements Iterator<E> {

        /**
         * Array to iterate over.
         */
        private final E[] mMembers;

        /**
         * Current position of next element to return in array.
         */
        private int mPosition;

        /**
         * Construct an array iterator from the specified array.
         *
         * @param members Array basis of the constructed iterator.
         */
        public Array(E[] members) {
            mMembers = members;
        }

        /**
         * Returns <code>true</code> if this iterator has more
         * elements.
         *
         * @return <code>true</code> if this iterator has more
         * elements.
         */
        public boolean hasNext() {
            return mPosition < mMembers.length;
        }

        /**
         * Returns the next element in the array.
         *
         * @return Next element in the array.
         * @throws NoSuchElementException If there are no more
         * elements left in the array to return.
         */
        public E next() {
            if (!hasNext())
                throw new NoSuchElementException();
            return mMembers[mPosition++];
        }

        /**
         * Sets position in underlying array corresponding to the most
         * recently returned token to <code>null</code>.
         *
         * @throws IllegalStateException If the <code>next</code>
         * method has not been called, or the <code>remove</code>
         * method has already been called after the last call to the
         * next method.
         */
        public void remove() {
            if (mPosition < 1)
                throw new IllegalStateException("Next not yet called.");
            if (mMembers[mPosition - 1] == null)
                throw new IllegalStateException("Remove already called.");
            mMembers[mPosition - 1] = null;
        }
    }

    /**
     * An <code>Iterators.ArraySlice</code> iterates over a slice of
     * an array specified by start index and length.
     *
     * @author  Bob Carpenter
     * @version 3.8
     * @since   LingPipe1.0
     * @param <E> the type of objects returned by the iterator
     */
    static class ArraySlice<E> implements Iterator<E> {

        /**
         * The underlying objects represented in this array iterator.
         */
        private final E[] mObjects;

        /**
         * Index of next element to return.
         */
        private int mNext;

        /**
         * Index one past the index of the last element to return.
         */
        private final int mLast;

        /**
         * Construct an iterator over the specified array of objects
         * that begins at the object at the specified start index
         * and carries through to the other objects.
         *
         * @param objects Array of objects over which to iterate.
         * @param start Index of first object to return.
         * @param length Number of objects to iterate.
         * @throws Illegal argument exception if {@code start < 0} or
         * {@code start + length > objects.length}.
         */
        public ArraySlice(E[] objects, int start, int length) {
            if (start < 0) {
                String msg = "Require start of slice to be non-negative." + " Found start=" + start;
                throw new IllegalArgumentException(msg);
            }
            if (start + length > objects.length) {
                String msg = "Start plus length must not exceed array length." + " Found objects.length="
                        + objects.length + " start=" + start + " length=" + length + " (start+length)="
                        + (start + length);
                throw new IllegalArgumentException(msg);
            }
            mObjects = objects;
            mNext = start;
            mLast = start + length;
        }

        /**
         * Returns <code>true</code> if there are more objects
         * to return.
         *
         * @return <code>true</code> if this iterator has more
         * elements.
         */
        public boolean hasNext() {
            return mNext < mLast;
        }

        /**
         * Returns the next object for this iterator, throwing
         * an exception if there are no more objects left.
         *
         * @return Next object from this iterator.
         * @throws NoSuchElementException If there are no more
         * elements to return.
         */
        public E next() {
            if (!hasNext())
                throw new NoSuchElementException();
            return mObjects[mNext++];
        }

        /**
         * Throws an <code>UnsupportedOperationException</code>.
         *
         * @throws UnsupportedOperationException If called.
         */
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }

    /**
     * An <code>Iterator.Empty</code> is an iterator with no
     * objects.  The method {@link #hasNext()} always returns
     * <code>false</code>, while the methods {@link #next()}
     * and {@link #remove()} always throw exceptions.
     *
     * @author  Bob Carpenter
     * @version 3.8
     * @since   LingPipe3.0
     * @param <E> the type of objects returned by the iterator
     */
    static class Empty<E> implements Iterator<E> {

        /**
         * Construct an empty iterator.
         */
        public Empty() {
            /* do nothing */
        }

        /**
         * Always returns <code>false</code>.
         *
         * @return <code>false</code>.
         */
        public boolean hasNext() {
            return false;
        }

        /**
         * Calling this method throws a no-such-element exception.
         *
         * @return Always throws an exception.
         * @throws NoSuchElementException Always.
         */
        public E next() {
            String msg = "No elements in empty iterator.";
            throw new NoSuchElementException(msg);
        }

        /**
         * Calling this method throws an illegal state exception.
         *
         * @throws IllegalStateException Always.
         */
        public void remove() {
            String msg = "No elements to remove in empty iterator.";
            throw new IllegalStateException(msg);
        }

    }

    /**
     * An <code>Iterator.Singleton</code> is an iterator over a
     * singleton object.
     *
     * @author  Bob Carpenter
     * @version 3.8
     * @since   LingPipe2.0
     * @param <E> the type of objects returned by the iterator
     */
    static class Singleton<E> implements Iterator<E> {

        /**
         * The single object to return.
         */
        private E mMember;

        /**
         * <code>true</code> if the single element has not already
         * been returned.
         */
        private boolean mHasNext = true;

        /**
         * Construct a singleton iterator that returns the specified
         * object.
         *
         * @param member Single member over which to iterate.
         */
        public Singleton(E member) {
            mMember = member;
        }

        /**
         * Returns <code>true</code> if the single member has not
         * already been returned.
         *
         * @return <code>true</code> if the single member has not
         * already been returned.
         */
        public boolean hasNext() {
            return mHasNext;
        }

        /**
         * Returns the singleton member if it has not yet been
         * returned, otherwise throw an exception.
         *
         * @return Singleton member if it has not yet been returned.
         * @throws NoSuchElementException If the singleton member has
         * already been returned and no elements remain.
         */
        public E next() {
            if (!mHasNext)
                throw new NoSuchElementException();
            mHasNext = false;
            E result = mMember;
            mMember = null;
            return result;
        }

        /**
         * Throws an unsupported operation exception.
         *
         * @throws UnsupportedOperationException Whenver called.
         */
        public void remove() {
            String msg = "This iterator does not support remove()." + " class=" + this.getClass();
            throw new UnsupportedOperationException(msg);
        }
    }

    /**
     * An <code>Iterators.Pair</code> provides an iterator
     * over a sequence of exactly two elements.
     *
     * @author  Bob Carpenter
     * @version 3.0
     * @since   LingPipe2.0
     * @param <E> the type of objects returned by the iterator
     */
    static class Pair<E> implements Iterator<E> {

        /**
         * Number of members returned so far.
         */
        private int mMembersReturned = 0;

        private E mMember1;
        private E mMember2;

        /**
         * Construct a pair iterator based on the containing
         * pair set.
         *
         * @param member1 First member.
         * @param member2 Second member.
         */
        public Pair(E member1, E member2) {
            mMember1 = member1;
            mMember2 = member2;
        }

        /**
         * Returns <code>true</code> if there are more elements
         * left to return.
         *
         * @return <code>true</code> if there are more elements
         * left to return.
         */
        public boolean hasNext() {
            return mMembersReturned < 2;
        }

        /**
         * Returns the next object in this pair iterator,
         * or throws an exception if there aren't any more.
         *
         * @return Next object in this pair iterator.
         */
        public E next() {
            if (mMembersReturned == 0) {
                ++mMembersReturned;
                E result1 = mMember1;
                mMember1 = null;
                return result1;
            }
            if (mMembersReturned == 1) {
                ++mMembersReturned;
                E result2 = mMember2;
                mMember2 = null;
                return result2;
            }
            throw new NoSuchElementException();
        }

        /**
         * Throws an unsupported operation exception.
         *
         * @throws UnsupportedOperationException Whenver called.
         */
        public void remove() {
            String msg = "This iterator does not support remove()." + " class=" + this.getClass();
            throw new UnsupportedOperationException(msg);
        }

    }

    /**
     * An <code>Iterators.Filter</code> filters the stream of objects
     * returned by another iterator by subjecting them to an acceptance
     * test.  Instances are constructed with a specified iterator to be
     * filtered; this filter is saved in this class and should not be
     * accessed by other methods.  Concrete subclasses must implement
     * {@link #accept(Object)}, which determines which of the elements
     * produced by the containediterator are returned.
     *
     * @author  Bob Carpenter
     * @version 3.0
     * @since   LingPipe1.0
     * @param <E> the type of objects returned by the iterator
     */
    public static abstract class Filter<E> implements Iterator<E> {

        private final Iterator<? extends E> mIterator;
        private boolean mFoundNext = false;
        private E mNext;

        /**
         * Construct a filtered iterator from the specified iterator.
         *
         * @param iterator Contained iterator to be filtered.
         */
        public Filter(Iterator<? extends E> iterator) {
            mIterator = iterator;
        }

        /**
         * Returns <code>true</code> for objects returned by the contained
         * iterator that should be returned by this iterator.
         *
         * @param x Object to test.
         * @return <code>true</code> if this object should be returned by
         * this iterator.
         */
        abstract public boolean accept(E x);

        /**
         * Returns <code>true</code> if calls to <code>next()</code> will
         * return a value.
         *
         * <P><i>Implementation note:</i> This iterator stores the next
         * element in a local variable after calls to this method.  Calls to
         * {@link #next()} remove this reference.
         *
         * @return <code>true</code> if calls to <code>next()</code> will
         * return a value.
         */
        public boolean hasNext() {
            if (mFoundNext)
                return true;
            while (mIterator.hasNext()) {
                E y = mIterator.next();
                if (accept(y)) {
                    mFoundNext = true;
                    mNext = y;
                    return true;
                }
            }
            return false;
        }

        /**
         * Returns the next value from the contained iterator that is accepted.
         * Acceptance is determined by the method {@link #accept(Object)}.
         *
         * @return Next object from the underlying iterator that passes
         * the acceptance test.
         * @throws NoSuchElementException If there are no more elements in
         * the underlying iterator that pass the acceptance test.
         */
        public E next() {
            if (!hasNext())
                throw new NoSuchElementException();
            mFoundNext = false;
            E result = mNext;
            mNext = null;
            return result;
        }

        /**
         * This operation is not supported.
         *
         * <P><i>Implementation Note:</i> Because calls to {@link
         * #hasNext()} must iterate over the contained iterator to find
         * the next acceptable object to return, it is not guaranteed that
         * the last element returned by this iterator is the same as the
         * last element returned by the underlying iterator.  Thus the
         * underlying iterator can't be used to do the removal without
         * tripping the fail-fast behavior of {@link Iterator}.
         *
         * @throws UnsupportedOperationException Always.
         */
        public void remove() {
            String msg = "Cannot remove from a filtered iterator.";
            throw new UnsupportedOperationException(msg);
        }

    }

    /**
     * An <code>Iterator.Modifier</code> uses a single abstract method
     * to operate on the elements returned by an underlying iterator
     * to return modified objects.  The {@link #remove()} and {@link
     * #hasNext()} methods are simply passed to the underlying iterator.
     * This implements the filter pattern, which is known as a map in
     * functional programming.
     *
     * @author  Bob Carpenter
     * @version 3.0
     * @since   LingPipe2.1
     * @param <E> the type of objects returned by the iterator
     */
    public static abstract class Modifier<E> implements Iterator<E> {
        private final Iterator<? extends E> mIt;

        /**
         * Construct a modifier from an underlying iterator.
         *
         * @param it Underlying iterator.
         */
        public Modifier(Iterator<? extends E> it) {
            mIt = it;
        }

        /**
         * Remove the next element by delegating the call to the the
         * underlying iterator.
         */
        public void remove() {
            mIt.remove();
        }

        /**
         * Returns <code>true</code> if the underlying iterator has
         * more elements.  This method is simply delegated to the
         * underlying iterator.
         *
         * @return <code>true</code> if this iterator has more
         * elements.
         */
        public boolean hasNext() {
            return mIt.hasNext();
        }

        /**
         * Returns the next element for this iterator, which is
         * the object returned by the underlying iterator after
         * undergoing modification by {@link #modify(Object)}.
         *
         * @return The modified next element from the underlying
         * iterator.
         */
        public E next() {
            return modify(mIt.next());
        }

        /**
         * This abstract method is applied to objects returned by the
         * underlying iterator to create the object returned by this
         * iterator. This method is called once for each call to
         * {@link #next()}.
         *
         * @param next Object returned by underlying iterator.
         * @return Object returned by this iterator.
         */
        public abstract E modify(E next);

    }

    /**
     * An <code>Iterators.Buffered</code> uses a single method to return
     * objects, buffering the result and returning it as the next element
     * if it is non-<code>null</code>.  This class does not support
     * <code>null</code> return values for {@link #next()}.  The {@link
     * #remove()} operation is unsupported, but may be overridden.
     *
     * @author  Bob Carpenter
     * @version 3.0
     * @since   LingPipe1.0
     * @param <E> the type of objects returned by the iterator
     */
    public static abstract class Buffered<E> implements Iterator<E> {

        private E mNext;

        /**
         * Construct a buffered iterator.  This constructor does not
         * do anything.
         */
        protected Buffered() {
            // do nothing
        }

        /**
         * Returns the next object for this iterator, or <code>null</code>
         * if there are no more objects.
         *
         * @return Next object for this iterator.
         */
        protected abstract E bufferNext();

        /**
         * Returns <code>true</code> if the next call to {@link #next()}
         * will return a non-<code>null</code> value.
         *
         * @return <code>true</code> if the next call to {@link #next()}
         * will return a non-<code>null</code> value.
         */
        public boolean hasNext() {
            return mNext != null || (mNext = bufferNext()) != null;
        }

        /**
         * Returns the next object for this iterator.
         *
         * @return The next object for this iterator.
         * @throws NoSuchElementException If there are no more elements.
         */
        public E next() {
            if (!hasNext())
                throw new NoSuchElementException();
            E result = mNext;
            mNext = null;
            return result;
        }

        /**
         * Throws an unsupported operation exception unless overridden by
         * a subclass.
         *
         * @throws UnsupportedOperationException Always.
         */
        public void remove() {
            throw new UnsupportedOperationException();
        }

    }

    /**
     * An <code>Iterators.Sequence</code> iterates over the elements of an
     * ordered sequence of iterators in turn.  Each iterator is exhausted
     * before moving to the next.  These iterators may be supplied as a
     * pair of iterators, as an array of iterators, or as an iterator of
     * iterators.  The sequence iterator delegates calls to {@link
     * #next()} and {@link #remove()} to the relevant iterator in the
     * underlying sequence of iterators.  For <code>next()</code>, this is
     * the current underlying iterator.  For <code>remove()</code>, it's
     * the last iterator whose <code>next()</code> element was called, and
     * it throws an illegal state exception if there isn't one.
     *
     * <P><I>Implementation Note:</I> Because of the requirements of
     * {@link Iterator#remove()}, a reference to the last iterator is
     * kept, as well as to the current iterator.  Otherwise, the sequence
     * iterator will release resources as soon as possible.  If the
     * supplied sequence is an array, the elements will not be
     * automatically returned from that array; it is simply wrapped in an
     * instance of {@link Iterators.Array}.
     *
     * @author  Bob Carpenter
     * @version 3.8
     * @since   LingPipe1.0
     * @param <E> the type of objects returned by the iterator
     */
    static class Sequence<E> implements Iterator<E> {

        private final Iterator<? extends Iterator<? extends E>> mIterators;
        private Iterator<? extends E> mCurrentIterator;
        private Iterator<? extends E> mLastIteratorNextCalled;

        /**
         * Construct a sequenc iterator that calls the pair of
         * iterators specified in turn.
         *
         * @param iterator1 First iterator.
         * @param iterator2 Second iterator.
         */
        public Sequence(Iterator<? extends E> iterator1, Iterator<? extends E> iterator2) {
            this(toIteratorIterator(iterator1, iterator2));
        }

        /**
         * Construct a sequence iterator that calls the iterators in the
         * specified array in the order they are given in the array.
         *
         * @param iterators Sequence of iterators.
         */
        public Sequence(Iterator<? extends E>[] iterators) {
            this(new Iterators.Array<Iterator<? extends E>>(iterators));
        }

        /**
         * Construct a sequence iterator that calls the iterators returned
         * by the iterator of iterators specified.  If one of the elements
         * is not an iterator, <code>hasNext()</code> and
         * <code>next()</code> will throw a
         * <code>ClassCastException</code>.
         *
         * @param iteratorOfIterators Iterator of iterators.
         */
        public Sequence(Iterator<? extends Iterator<? extends E>> iteratorOfIterators) {
            mIterators = iteratorOfIterators;
        }

        /**
         * Returns <code>true</code> if this iterator has another element.
         * This sequence of iterators has another element if it has
         * another iterator that has another element.
         *
         * @return <code>true</code> if this sequence of iterators
         * has another iterator with another element.
         * @throws ClassCastException If an object is returned by
         * the iterator of iterators specified at construction time
         * that is not an iterator.
         */
        public boolean hasNext() {
            if (mCurrentIterator == null)
                nextIterator(); // get started
            for (; mCurrentIterator != null; nextIterator())
                if (mCurrentIterator.hasNext())
                    return true;
            return false;
        }

        /**
         * Return the next element returned by the next iterator in the
         * iterator sequence.
         *
         * @return The next object in the iteration.
         * @throws ClassCastException If an object is returned by
         * the iterator of iterators specified at construction time
         * that is not an iterator.
         */
        public E next() {
            if (!hasNext())
                throw new NoSuchElementException();
            mLastIteratorNextCalled = mCurrentIterator;
            return mCurrentIterator.next();
        }

        /**
         * Removes the last element returned by this iterator from the
         * collection underlying the iterator from which it was returned.
         * The method can only be called once per call to
         * <code>next()</code>.
            
         * @throws IllegalStateException If <code>next()</code> has not
         * yet been called, or <code>remove()</code> method has
         * been called after the last call to <code>next()</code>.
         */
        public void remove() {
            if (mLastIteratorNextCalled == null)
                throw new IllegalStateException("next() not yet called.");
            mLastIteratorNextCalled.remove();
            mLastIteratorNextCalled = null;
        }

        private void nextIterator() {
            // possible cast exception
            mCurrentIterator = mIterators.hasNext() ? mIterators.next() : null;
        }

        static <E> Iterator<? extends Iterator<? extends E>> toIteratorIterator(Iterator<? extends E> it1,
                Iterator<? extends E> it2) {
            ArrayList<Iterator<? extends E>> list = new ArrayList<Iterator<? extends E>>(2);
            list.add(it1);
            list.add(it2);
            return list.iterator();
        }

    }

    /**
     * A {@code Iterators.PrimitiveInt} is an integer iterator that
     * also allows objects to be accessed as primitive {@code int}
     * values.
     *
     * <p>The method {@link #next()} returns an {@code Integer},
     * whereas {@link #nextPrimitive()} returns a primitive {@code
     * int} value.  Using either one will advanced the iterator to the
     * next element.
     *
     * <p><i>Implementation Note:</i> Using the standard iterator
     * implementation as {@code Integer} requires boxing of the
     * primitive values as objects.  Therefore, use the method
     * {@code nextPrimitive()} wherever possible.
     *
     * @author Mike Ross
     * @author Bob Carpenter
     * @version 3.8
     * @since Lingpipe3.8
     */
    public static abstract class PrimitiveInt implements Iterator<Integer> {

        /**
         * Returns the next primitive integer.
         *
         * @return The next primitive integer.
         */
        abstract public int nextPrimitive();

        /**
         * Returns {@code true} if there is another integer in the
         * iteration.
         *
         * @return {@code true} if there is another integer in the
         * iteration.
         */
        abstract public boolean hasNext();

        /**
         * Throws unsupported operation exception.
         *
         * @throws UnsupportedOperationException Always.
         */
        public void remove() {
            String msg = "Iterators.PrimitiveInt does not support remove.";
            throw new UnsupportedOperationException(msg);
        }

        /**
         * Returns the next integer result.
         *
         * <p><i>Implementation Note:</i> Requires boxing the
         * primitive {@code int} returned by {@link #nextPrimitive()}.
         *
         * @return The next integer.
         */
        public Integer next() {
            return nextPrimitive();
        }
    }

    /**
     * Construct an Integer iterator from 0 (inclusive) the specified
     * end point (exclusive).  The returned iterator does not support
     * {@code remove()}.
     *
     * @param end One plus the last integer returned.
     */
    public static PrimitiveInt intRange(int end) {
        return new IntRange(0, end);
    }

    /**
     * Returns a newly constructed primitive integer iterator that
     * iterates from the start (inclusive) to end (exclusive).
     *
     * <p>The returned iterator does not support {@code remove()}.
     *
     * @param start The first and lowest value to return.
     * @param end One plus the last integer returned.
     * @throws IllegalArgumentException If {@code start > end}.
     */
    public static PrimitiveInt intRange(int start, int end) {
        return new IntRange(start, end);
    }

    /**
     * Returns an iterator over the array of primitive integers
     * specified.  
     *
     * <p>There are no order restrictions on the array -- its elements
     * may be in any order and may contain duplicates.
     *
     * <p>The returned iterator does not support {@code remove()}.
     *
     * @param members Array of members to iterate.
     */
    public static PrimitiveInt intArray(int[] members) {
        return new IntArray(members);
    }

    /**
     * See {@link #intRange(int,int)} for usage.
     *
     * @author  Mike Ross
     * @version 3.8
     * @since   Lingpipe3.8
     */
    static class IntRange extends PrimitiveInt {
        private int mCur;
        private final int mEnd;

        public IntRange(int start, int end) {
            if (end < start) {
                String msg = "End point must be >= start point." + " Found start=" + start + " end=" + end;
                throw new IllegalArgumentException(msg);
            }
            mCur = start;
            mEnd = end;
        }

        public boolean hasNext() {
            return mCur < mEnd;
        }

        public int nextPrimitive() {
            if (!hasNext())
                throw new NoSuchElementException();
            return mCur++;
        }
    }

    /**
     * See {@link #intArray(int[])} for usage.
     *
     * @author  Mike Ross
     * @version 3.8
     * @since   Lingpipe3.8
     */
    static class IntArray extends PrimitiveInt {
        private final int[] mMembers;
        private int mPosition;

        public IntArray(int[] members) {
            mMembers = members;
        }

        public boolean hasNext() {
            return mPosition < mMembers.length;
        }

        public int nextPrimitive() {
            if (!hasNext())
                throw new NoSuchElementException();
            return mMembers[mPosition++];
        }

    }

}