    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;
    018
    019import java.lang.reflect.Array;
    020import java.lang.reflect.Method;
    021import java.util.ArrayList;
    022import java.util.Collection;
    023import java.util.Comparator;
    024import java.util.Dictionary;
    025import java.util.Enumeration;
    026import java.util.Iterator;
    027import java.util.List;
    028import java.util.ListIterator;
    029import java.util.Map;
    030import java.util.Objects;
    031import java.util.Spliterator;
    032import java.util.Spliterators;
    033import java.util.function.IntFunction;
    034import java.util.stream.Stream;
    035import java.util.stream.StreamSupport;
    036
    037import org.apache.commons.collections4.functors.EqualPredicate;
    038import org.apache.commons.collections4.iterators.ArrayIterator;
    039import org.apache.commons.collections4.iterators.ArrayListIterator;
    040import org.apache.commons.collections4.iterators.BoundedIterator;
    041import org.apache.commons.collections4.iterators.CollatingIterator;
    042import org.apache.commons.collections4.iterators.EmptyIterator;
    043import org.apache.commons.collections4.iterators.EmptyListIterator;
    044import org.apache.commons.collections4.iterators.EmptyMapIterator;
    045import org.apache.commons.collections4.iterators.EmptyOrderedIterator;
    046import org.apache.commons.collections4.iterators.EmptyOrderedMapIterator;
    047import org.apache.commons.collections4.iterators.EnumerationIterator;
    048import org.apache.commons.collections4.iterators.FilterIterator;
    049import org.apache.commons.collections4.iterators.FilterListIterator;
    050import org.apache.commons.collections4.iterators.IteratorChain;
    051import org.apache.commons.collections4.iterators.IteratorEnumeration;
    052import org.apache.commons.collections4.iterators.IteratorIterable;
    053import org.apache.commons.collections4.iterators.LazyIteratorChain;
    054import org.apache.commons.collections4.iterators.ListIteratorWrapper;
    055import org.apache.commons.collections4.iterators.LoopingIterator;
    056import org.apache.commons.collections4.iterators.LoopingListIterator;
    057import org.apache.commons.collections4.iterators.NodeListIterator;
    058import org.apache.commons.collections4.iterators.ObjectArrayIterator;
    059import org.apache.commons.collections4.iterators.ObjectArrayListIterator;
    060import org.apache.commons.collections4.iterators.ObjectGraphIterator;
    061import org.apache.commons.collections4.iterators.PeekingIterator;
    062import org.apache.commons.collections4.iterators.PushbackIterator;
    063import org.apache.commons.collections4.iterators.SingletonIterator;
    064import org.apache.commons.collections4.iterators.SingletonListIterator;
    065import org.apache.commons.collections4.iterators.SkippingIterator;
    066import org.apache.commons.collections4.iterators.TransformIterator;
    067import org.apache.commons.collections4.iterators.UnmodifiableIterator;
    068import org.apache.commons.collections4.iterators.UnmodifiableListIterator;
    069import org.apache.commons.collections4.iterators.UnmodifiableMapIterator;
    070import org.apache.commons.collections4.iterators.ZippingIterator;
    071import org.w3c.dom.Node;
    072import org.w3c.dom.NodeList;
    073
    074/**
    075 * Provides static utility methods and decorators for {@link Iterator}
    076 * instances. The implementations are provided in the iterators subpackage.
    077 *
    078 * @since 2.1
    079 */
    080public class IteratorUtils {
    081    // validation is done in this class in certain cases because the
    082    // public classes allow invalid states
    083
    084    /**
    085     * An iterator over no elements.
    086     */
    087    @SuppressWarnings("rawtypes")
    088    public static final ResettableIterator EMPTY_ITERATOR = EmptyIterator.RESETTABLE_INSTANCE;
    089
    090    /**
    091     * A list iterator over no elements.
    092     */
    093    @SuppressWarnings("rawtypes")
    094    public static final ResettableListIterator EMPTY_LIST_ITERATOR = EmptyListIterator.RESETTABLE_INSTANCE;
    095
    096    /**
    097     * An ordered iterator over no elements.
    098     */
    099    @SuppressWarnings("rawtypes")
    100    public static final OrderedIterator EMPTY_ORDERED_ITERATOR = EmptyOrderedIterator.INSTANCE;
    101
    102    /**
    103     * A map iterator over no elements.
    104     */
    105    @SuppressWarnings("rawtypes")
    106    public static final MapIterator EMPTY_MAP_ITERATOR = EmptyMapIterator.INSTANCE;
    107
    108    /**
    109     * An ordered map iterator over no elements.
    110     */
    111    @SuppressWarnings("rawtypes")
    112    public static final OrderedMapIterator EMPTY_ORDERED_MAP_ITERATOR = EmptyOrderedMapIterator.INSTANCE;
    113    /**
    114     * Default delimiter used to delimit elements while converting an Iterator
    115     * to its String representation.
    116     */
    117    private static final String DEFAULT_TOSTRING_DELIMITER = ", ";
    118
    119    /**
    120     * Gets an iterator over an object array.
    121     *
    122     * @param <E> the element type
    123     * @param array  the array over which to iterate
    124     * @return an iterator over the array
    125     * @throws NullPointerException if array is null
    126     */
    127    public static <E> ResettableIterator<E> arrayIterator(final E... array) {
    128        return new ObjectArrayIterator<>(array);
    129    }
    130
    131    /**
    132     * Gets an iterator over the end part of an object array.
    133     *
    134     * @param <E> the element type
    135     * @param array  the array over which to iterate
    136     * @param start  the index to start iterating at
    137     * @return an iterator over part of the array
    138     * @throws IndexOutOfBoundsException if start is less than zero or greater
    139     *   than the length of the array
    140     * @throws NullPointerException if array is null
    141     */
    142    public static <E> ResettableIterator<E> arrayIterator(final E[] array, final int start) {
    143        return new ObjectArrayIterator<>(array, start);
    144    }
    145
    146    /**
    147     * Gets an iterator over part of an object array.
    148     *
    149     * @param <E> the element type
    150     * @param array  the array over which to iterate
    151     * @param start  the index to start iterating at
    152     * @param end  the index to finish iterating at
    153     * @return an iterator over part of the array
    154     * @throws IndexOutOfBoundsException if array bounds are invalid
    155     * @throws IllegalArgumentException if end is before start
    156     * @throws NullPointerException if array is null
    157     */
    158    public static <E> ResettableIterator<E> arrayIterator(final E[] array, final int start, final int end) {
    159        return new ObjectArrayIterator<>(array, start, end);
    160    }
    161
    162    /**
    163     * Gets an iterator over an object or primitive array.
    164     * <p>
    165     * This method will handle primitive arrays as well as object arrays.
    166     * The primitives will be wrapped in the appropriate wrapper class.
    167     * </p>
    168     *
    169     * @param <E> the element type
    170     * @param array  the array over which to iterate
    171     * @return an iterator over the array
    172     * @throws IllegalArgumentException if the array is not an array
    173     * @throws NullPointerException if array is null
    174     */
    175    public static <E> ResettableIterator<E> arrayIterator(final Object array) {
    176        return new ArrayIterator<>(array);
    177    }
    178
    179    /**
    180     * Gets an iterator over the end part of an object or primitive array.
    181     * <p>
    182     * This method will handle primitive arrays as well as object arrays.
    183     * The primitives will be wrapped in the appropriate wrapper class.
    184     * </p>
    185     *
    186     * @param <E> the element type
    187     * @param array  the array over which to iterate
    188     * @param start  the index to start iterating at
    189     * @return an iterator over part of the array
    190     * @throws IllegalArgumentException if the array is not an array
    191     * @throws IndexOutOfBoundsException if start is less than zero or greater
    192     *   than the length of the array
    193     * @throws NullPointerException if array is null
    194     */
    195    public static <E> ResettableIterator<E> arrayIterator(final Object array, final int start) {
    196        return new ArrayIterator<>(array, start);
    197    }
    198
    199    /**
    200     * Gets an iterator over part of an object or primitive array.
    201     * <p>
    202     * This method will handle primitive arrays as well as object arrays.
    203     * The primitives will be wrapped in the appropriate wrapper class.
    204     * </p>
    205     *
    206     * @param <E> the element type
    207     * @param array  the array over which to iterate
    208     * @param start  the index to start iterating at
    209     * @param end  the index to finish iterating at
    210     * @return an iterator over part of the array
    211     * @throws IllegalArgumentException if the array is not an array or end is before start
    212     * @throws IndexOutOfBoundsException if array bounds are invalid
    213     * @throws NullPointerException if array is null
    214     */
    215    public static <E> ResettableIterator<E> arrayIterator(final Object array, final int start, final int end) {
    216        return new ArrayIterator<>(array, start, end);
    217    }
    218
    219    /**
    220     * Gets a list iterator over an object array.
    221     *
    222     * @param <E> the element type
    223     * @param array  the array over which to iterate
    224     * @return a list iterator over the array
    225     * @throws NullPointerException if array is null
    226     */
    227    public static <E> ResettableListIterator<E> arrayListIterator(final E... array) {
    228        return new ObjectArrayListIterator<>(array);
    229    }
    230
    231    /**
    232     * Gets a list iterator over the end part of an object array.
    233     *
    234     * @param <E> the element type
    235     * @param array  the array over which to iterate
    236     * @param start  the index to start iterating at
    237     * @return a list iterator over part of the array
    238     * @throws IndexOutOfBoundsException if start is less than zero
    239     * @throws NullPointerException if array is null
    240     */
    241    public static <E> ResettableListIterator<E> arrayListIterator(final E[] array, final int start) {
    242        return new ObjectArrayListIterator<>(array, start);
    243    }
    244
    245    /**
    246     * Gets a list iterator over part of an object array.
    247     *
    248     * @param <E> the element type
    249     * @param array  the array over which to iterate
    250     * @param start  the index to start iterating at
    251     * @param end  the index to finish iterating at
    252     * @return a list iterator over part of the array
    253     * @throws IndexOutOfBoundsException if array bounds are invalid
    254     * @throws IllegalArgumentException if end is before start
    255     * @throws NullPointerException if array is null
    256     */
    257    public static <E> ResettableListIterator<E> arrayListIterator(final E[] array, final int start, final int end) {
    258        return new ObjectArrayListIterator<>(array, start, end);
    259    }
    260
    261    /**
    262     * Gets a list iterator over an object or primitive array.
    263     * <p>
    264     * This method will handle primitive arrays as well as object arrays.
    265     * The primitives will be wrapped in the appropriate wrapper class.
    266     * </p>
    267     *
    268     * @param <E> the element type
    269     * @param array  the array over which to iterate
    270     * @return a list iterator over the array
    271     * @throws IllegalArgumentException if the array is not an array
    272     * @throws NullPointerException if array is null
    273     */
    274    public static <E> ResettableListIterator<E> arrayListIterator(final Object array) {
    275        return new ArrayListIterator<>(array);
    276    }
    277
    278    /**
    279     * Gets a list iterator over the end part of an object or primitive array.
    280     * <p>
    281     * This method will handle primitive arrays as well as object arrays.
    282     * The primitives will be wrapped in the appropriate wrapper class.
    283     * </p>
    284     *
    285     * @param <E> the element type
    286     * @param array  the array over which to iterate
    287     * @param start  the index to start iterating at
    288     * @return a list iterator over part of the array
    289     * @throws IllegalArgumentException if the array is not an array
    290     * @throws IndexOutOfBoundsException if start is less than zero
    291     * @throws NullPointerException if array is null
    292     */
    293    public static <E> ResettableListIterator<E> arrayListIterator(final Object array, final int start) {
    294        return new ArrayListIterator<>(array, start);
    295    }
    296
    297    /**
    298     * Gets a list iterator over part of an object or primitive array.
    299     * <p>
    300     * This method will handle primitive arrays as well as object arrays.
    301     * The primitives will be wrapped in the appropriate wrapper class.
    302     * </p>
    303     *
    304     * @param <E> the element type
    305     * @param array  the array over which to iterate
    306     * @param start  the index to start iterating at
    307     * @param end  the index to finish iterating at
    308     * @return a list iterator over part of the array
    309     * @throws IllegalArgumentException if the array is not an array or end is before start
    310     * @throws IndexOutOfBoundsException if array bounds are invalid
    311     * @throws NullPointerException if array is null
    312     */
    313    public static <E> ResettableListIterator<E> arrayListIterator(final Object array, final int start, final int end) {
    314        return new ArrayListIterator<>(array, start, end);
    315    }
    316
    317    /**
    318     * Gets an enumeration that wraps an iterator.
    319     *
    320     * @param <E> the element type
    321     * @param iterator  the iterator to use, may not be null
    322     * @return a new enumeration
    323     * @throws NullPointerException if iterator is null
    324     */
    325    public static <E> Enumeration<E> asEnumeration(final Iterator<? extends E> iterator) {
    326        return new IteratorEnumeration<>(Objects.requireNonNull(iterator, "iterator"));
    327    }
    328
    329    /**
    330     * Gets an {@link Iterable} that wraps an iterator.  The returned {@link Iterable} can be
    331     * used for a single iteration.
    332     *
    333     * @param <E> the element type
    334     * @param iterator  the iterator to use, may not be null
    335     * @return a new, single use {@link Iterable}
    336     * @throws NullPointerException if iterator is null
    337     */
    338    public static <E> Iterable<E> asIterable(final Iterator<? extends E> iterator) {
    339        Objects.requireNonNull(iterator, "iterator");
    340        return new IteratorIterable<>(iterator, false);
    341    }
    342
    343    /**
    344     * Gets an iterator that provides an iterator view of the given enumeration.
    345     *
    346     * @param <E> the element type
    347     * @param enumeration  the enumeration to use, may not be null
    348     * @return a new iterator
    349     * @throws NullPointerException if enumeration is null
    350     */
    351    public static <E> Iterator<E> asIterator(final Enumeration<? extends E> enumeration) {
    352        return new EnumerationIterator<>(Objects.requireNonNull(enumeration, "enumeration"));
    353    }
    354
    355    /**
    356     * Gets an iterator that provides an iterator view of the given enumeration
    357     * that will remove elements from the specified collection.
    358     *
    359     * @param <E> the element type
    360     * @param enumeration  the enumeration to use, may not be null
    361     * @param removeCollection  the collection to remove elements from, may not be null
    362     * @return a new iterator
    363     * @throws NullPointerException if enumeration or removeCollection is null
    364     */
    365    public static <E> Iterator<E> asIterator(final Enumeration<? extends E> enumeration,
    366                                             final Collection<? super E> removeCollection) {
    367        return new EnumerationIterator<>(Objects.requireNonNull(enumeration, "enumeration"),
    368                Objects.requireNonNull(removeCollection, "removeCollection"));
    369    }
    370
    371    /**
    372     * Gets an iterable that wraps an iterator.  The returned iterable can be
    373     * used for multiple iterations.
    374     *
    375     * @param <E> the element type
    376     * @param iterator  the iterator to use, may not be null
    377     * @return a new, multiple use iterable
    378     * @throws NullPointerException if iterator is null
    379     */
    380    public static <E> Iterable<E> asMultipleUseIterable(final Iterator<? extends E> iterator) {
    381        Objects.requireNonNull(iterator, "iterator");
    382        return new IteratorIterable<>(iterator, true);
    383    }
    384
    385    // Bounded
    386    /**
    387     * Decorates the specified iterator to return at most the given number
    388     * of elements.
    389     *
    390     * @param <E> the element type
    391     * @param iterator  the iterator to decorate
    392     * @param max  the maximum number of elements returned by this iterator
    393     * @return a new bounded iterator
    394     * @throws NullPointerException if the iterator is null
    395     * @throws IllegalArgumentException if max is negative
    396     * @since 4.1
    397     */
    398    public static <E> BoundedIterator<E> boundedIterator(final Iterator<? extends E> iterator, final long max) {
    399        return boundedIterator(iterator, 0, max);
    400    }
    401
    402    /**
    403     * Decorates the specified iterator to return at most the given number
    404     * of elements, skipping all elements until the iterator reaches the
    405     * position at {@code offset}.
    406     * <p>
    407     * The iterator is immediately advanced until it reaches the position at
    408     * {@code offset}, incurring O(n) time.
    409     * </p>
    410     *
    411     * @param <E> the element type
    412     * @param iterator  the iterator to decorate
    413     * @param offset  the index of the first element of the decorated iterator to return
    414     * @param max  the maximum number of elements returned by this iterator
    415     * @return a new bounded iterator
    416     * @throws NullPointerException if the iterator is null
    417     * @throws IllegalArgumentException if either offset or max is negative
    418     * @since 4.1
    419     */
    420    public static <E> BoundedIterator<E> boundedIterator(final Iterator<? extends E> iterator,
    421                                                         final long offset, final long max) {
    422        return new BoundedIterator<>(iterator, offset, max);
    423    }
    424
    425    /**
    426     * Gets an iterator that iterates through a collections of {@link Iterator}s
    427     * one after another.
    428     *
    429     * @param <E> the element type
    430     * @param iterators  the iterators to use, not null or empty or contain nulls
    431     * @return a combination iterator over the iterators
    432     * @throws NullPointerException if iterators collection is null or contains a null
    433     * @throws ClassCastException if the iterators collection contains the wrong object type
    434     */
    435    public static <E> Iterator<E> chainedIterator(final Collection<? extends Iterator<? extends E>> iterators) {
    436        return new IteratorChain<>(iterators);
    437    }
    438
    439    /**
    440     * Gets an iterator that iterates through an array of {@link Iterator}s
    441     * one after another.
    442     *
    443     * @param <E> the element type
    444     * @param iterators  the iterators to use, not null or empty or contain nulls
    445     * @return a combination iterator over the iterators
    446     * @throws NullPointerException if iterators array is null or contains a null
    447     */
    448    public static <E> Iterator<E> chainedIterator(final Iterator<? extends E>... iterators) {
    449        return new IteratorChain<>(iterators);
    450    }
    451
    452    /**
    453     * Gets an iterator that iterates through two {@link Iterator}s
    454     * one after another.
    455     *
    456     * @param <E> the element type
    457     * @param iterator1  the first iterator to use, not null
    458     * @param iterator2  the second iterator to use, not null
    459     * @return a combination iterator over the iterators
    460     * @throws NullPointerException if either iterator is null
    461     */
    462    public static <E> Iterator<E> chainedIterator(final Iterator<? extends E> iterator1,
    463                                                  final Iterator<? extends E> iterator2) {
    464        // keep a version with two iterators to avoid the following warning in client code (Java 5 & 6)
    465        // "A generic array of E is created for a varargs parameter"
    466        return new IteratorChain<>(iterator1, iterator2);
    467    }
    468
    469    /**
    470     * Gets an iterator that iterates through an {@link Iterator} of Iterators one after another.
    471     *
    472     * @param <E>       the element type
    473     * @param iterators the iterators to use, not null or empty or contain nulls
    474     * @return a combination iterator over the iterators
    475     * @throws NullPointerException if iterators collection is null or contains a null
    476     * @throws ClassCastException   if the iterators collection contains the wrong object type
    477     * @since 4.5.0-M3
    478     */
    479    public static <E> Iterator<E> chainedIterator(final Iterator<? extends Iterator<? extends E>> iterators) {
    480        return new LazyIteratorChain<E>() {
    481
    482            @Override
    483            protected Iterator<? extends E> nextIterator(final int count) {
    484                return iterators.hasNext() ? iterators.next() : null;
    485            }
    486
    487        };
    488    }
    489
    490    /**
    491     * Gets an iterator that provides an ordered iteration over the elements
    492     * contained in a collection of {@link Iterator}s.
    493     * <p>
    494     * Given two ordered {@link Iterator}s {@code A} and {@code B},
    495     * the {@link Iterator#next()} method will return the lesser of
    496     * {@code A.next()} and {@code B.next()} and so on.
    497     * </p>
    498     * <p>
    499     * The comparator is optional. If null is specified then natural order is used.
    500     * </p>
    501     *
    502     * @param <E> the element type
    503     * @param comparator  the comparator to use, may be null for natural order
    504     * @param iterators  the iterators to use, not null or empty or contain nulls
    505     * @return a combination iterator over the iterators
    506     * @throws NullPointerException if iterators collection is null or contains a null
    507     * @throws ClassCastException if the iterators collection contains the wrong object type
    508     */
    509    public static <E> Iterator<E> collatedIterator(final Comparator<? super E> comparator,
    510                                                   final Collection<Iterator<? extends E>> iterators) {
    511        @SuppressWarnings("unchecked")
    512        final Comparator<E> comp =
    513            comparator == null ? ComparatorUtils.NATURAL_COMPARATOR : (Comparator<E>) comparator;
    514        return new CollatingIterator<>(comp, iterators);
    515    }
    516
    517    /**
    518     * Gets an iterator that provides an ordered iteration over the elements
    519     * contained in an array of {@link Iterator}s.
    520     * <p>
    521     * Given two ordered {@link Iterator}s {@code A} and {@code B},
    522     * the {@link Iterator#next()} method will return the lesser of
    523     * {@code A.next()} and {@code B.next()} and so on.
    524     * </p>
    525     * <p>
    526     * The comparator is optional. If null is specified then natural order is used.
    527     * </p>
    528     *
    529     * @param <E> the element type
    530     * @param comparator  the comparator to use, may be null for natural order
    531     * @param iterators  the iterators to use, not null or empty or contain nulls
    532     * @return a combination iterator over the iterators
    533     * @throws NullPointerException if iterators array is null or contains a null value
    534     */
    535    public static <E> Iterator<E> collatedIterator(final Comparator<? super E> comparator,
    536                                                   final Iterator<? extends E>... iterators) {
    537        @SuppressWarnings("unchecked")
    538        final Comparator<E> comp =
    539            comparator == null ? ComparatorUtils.NATURAL_COMPARATOR : (Comparator<E>) comparator;
    540        return new CollatingIterator<>(comp, iterators);
    541    }
    542
    543    /**
    544     * Gets an iterator that provides an ordered iteration over the elements
    545     * contained in a collection of ordered {@link Iterator}s.
    546     * <p>
    547     * Given two ordered {@link Iterator}s {@code A} and {@code B},
    548     * the {@link Iterator#next()} method will return the lesser of
    549     * {@code A.next()} and {@code B.next()}.
    550     * </p>
    551     * <p>
    552     * The comparator is optional. If null is specified then natural order is used.
    553     * </p>
    554     *
    555     * @param <E> the element type
    556     * @param comparator  the comparator to use, may be null for natural order
    557     * @param iterator1  the first iterators to use, not null
    558     * @param iterator2  the first iterators to use, not null
    559     * @return a combination iterator over the iterators
    560     * @throws NullPointerException if either iterator is null
    561     */
    562    public static <E> Iterator<E> collatedIterator(final Comparator<? super E> comparator,
    563                                                   final Iterator<? extends E> iterator1,
    564                                                   final Iterator<? extends E> iterator2) {
    565        @SuppressWarnings("unchecked")
    566        final Comparator<E> comp =
    567            comparator == null ? ComparatorUtils.NATURAL_COMPARATOR : (Comparator<E>) comparator;
    568        return new CollatingIterator<>(comp, iterator1, iterator2);
    569    }
    570
    571    /**
    572     * Checks if the object is contained in the given iterator.
    573     * <p>
    574     * A {@code null} or empty iterator returns false.
    575     * </p>
    576     *
    577     * @param <E> the type of object the {@link Iterator} contains
    578     * @param iterator  the iterator to check, may be null
    579     * @param object  the object to check
    580     * @return true if the object is contained in the iterator, false otherwise
    581     * @since 4.1
    582     */
    583    public static <E> boolean contains(final Iterator<E> iterator, final Object object) {
    584        return matchesAny(iterator, EqualPredicate.equalPredicate(object));
    585    }
    586
    587    /**
    588     * Gets an empty iterator.
    589     * <p>
    590     * This iterator is a valid iterator object that will iterate over nothing.
    591     * </p>
    592     *
    593     * @param <E> the element type
    594     * @return an iterator over nothing
    595     */
    596    public static <E> ResettableIterator<E> emptyIterator() {
    597        return EmptyIterator.<E>resettableEmptyIterator();
    598    }
    599
    600    /**
    601     * Gets an empty list iterator.
    602     * <p>
    603     * This iterator is a valid list iterator object that will iterate
    604     * over nothing.
    605     * </p>
    606     *
    607     * @param <E> the element type
    608     * @return a list iterator over nothing
    609     */
    610    public static <E> ResettableListIterator<E> emptyListIterator() {
    611        return EmptyListIterator.<E>resettableEmptyListIterator();
    612    }
    613
    614    /**
    615     * Gets an empty map iterator.
    616     * <p>
    617     * This iterator is a valid map iterator object that will iterate
    618     * over nothing.
    619     * </p>
    620     *
    621     * @param <K> the key type
    622     * @param <V> the value type
    623     * @return a map iterator over nothing
    624     */
    625    public static <K, V> MapIterator<K, V> emptyMapIterator() {
    626        return EmptyMapIterator.<K, V>emptyMapIterator();
    627    }
    628
    629    /**
    630     * Gets an empty ordered iterator.
    631     * <p>
    632     * This iterator is a valid iterator object that will iterate
    633     * over nothing.
    634     * </p>
    635     *
    636     * @param <E> the element type
    637     * @return an ordered iterator over nothing
    638     */
    639    public static <E> OrderedIterator<E> emptyOrderedIterator() {
    640        return EmptyOrderedIterator.<E>emptyOrderedIterator();
    641    }
    642
    643    /**
    644     * Gets an empty ordered map iterator.
    645     * <p>
    646     * This iterator is a valid map iterator object that will iterate
    647     * over nothing.
    648     * </p>
    649     *
    650     * @param <K> the key type
    651     * @param <V> the value type
    652     * @return a map iterator over nothing
    653     */
    654    public static <K, V> OrderedMapIterator<K, V> emptyOrderedMapIterator() {
    655        return EmptyOrderedMapIterator.<K, V>emptyOrderedMapIterator();
    656    }
    657
    658    /**
    659     * Gets an iterator that filters another iterator.
    660     * <p>
    661     * The returned iterator will only return objects that match the specified
    662     * filtering predicate.
    663     * </p>
    664     *
    665     * @param <E> the element type
    666     * @param iterator  the iterator to use, not null
    667     * @param predicate  the predicate to use as a filter, not null
    668     * @return a new filtered iterator
    669     * @throws NullPointerException if either parameter is null
    670     */
    671    public static <E> Iterator<E> filteredIterator(final Iterator<? extends E> iterator,
    672                                                   final Predicate<? super E> predicate) {
    673        Objects.requireNonNull(iterator, "iterator");
    674        Objects.requireNonNull(predicate, "predicate");
    675        return new FilterIterator<>(iterator, predicate);
    676    }
    677
    678    /**
    679     * Gets a list iterator that filters another list iterator.
    680     * <p>
    681     * The returned iterator will only return objects that match the specified
    682     * filtering predicate.
    683     * </p>
    684     *
    685     * @param <E> the element type
    686     * @param listIterator  the list iterator to use, not null
    687     * @param predicate  the predicate to use as a filter, not null
    688     * @return a new filtered iterator
    689     * @throws NullPointerException if either parameter is null
    690     */
    691    public static <E> ListIterator<E> filteredListIterator(final ListIterator<? extends E> listIterator,
    692            final Predicate<? super E> predicate) {
    693
    694        Objects.requireNonNull(listIterator, "listIterator");
    695        Objects.requireNonNull(predicate, "predicate");
    696        return new FilterListIterator<>(listIterator, predicate);
    697    }
    698
    699    /**
    700     * Finds the first element in the given iterator which matches the given predicate.
    701     * <p>
    702     * A {@code null} or empty iterator returns null.
    703     * </p>
    704     *
    705     * @param <E> the element type
    706     * @param iterator  the iterator to search, may be null
    707     * @param predicate  the predicate to use, must not be null
    708     * @return the first element of the iterator which matches the predicate or null if none could be found
    709     * @throws NullPointerException if predicate is null
    710     * @since 4.1
    711     */
    712    public static <E> E find(final Iterator<E> iterator, final Predicate<? super E> predicate) {
    713        return find(iterator, predicate, null);
    714    }
    715
    716    /**
    717     * Finds the first element in the given iterator which matches the given predicate.
    718     * <p>
    719     * A {@code null} or empty iterator returns {@code defaultValue}.
    720     * </p>
    721     *
    722     * @param <E>          the element type.
    723     * @param iterator     the iterator to search, may be null.
    724     * @param predicate    the predicate to use, must not be null.
    725     * @param defaultValue the default value, may be null.
    726     * @return the first element of the iterator which matches the predicate or null if none could be found.
    727     * @throws NullPointerException if predicate is null.
    728     */
    729    private static <E> E find(final Iterator<E> iterator, final Predicate<? super E> predicate, final E defaultValue) {
    730        Objects.requireNonNull(predicate, "predicate");
    731        if (iterator != null) {
    732            while (iterator.hasNext()) {
    733                final E element = iterator.next();
    734                if (predicate.test(element)) {
    735                    return element;
    736                }
    737            }
    738        }
    739        return defaultValue;
    740    }
    741
    742    /**
    743     * Shortcut for {@code get(iterator, 0)}.
    744     * <p>
    745     * Returns the {@code first} value in {@link Iterator}, throwing
    746     * {@code IndexOutOfBoundsException} if there is no such element.
    747     * </p>
    748     * <p>
    749     * The Iterator is advanced to {@code 0} (or to the end, if
    750     * {@code 0} exceeds the number of entries) as a side effect of this method.
    751     * </p>
    752     * @param <E> the type of object in the {@link Iterator}
    753     * @param iterator the iterator to get a value from
    754     * @return the first object
    755     * @throws IndexOutOfBoundsException if the request is invalid
    756     * @since 4.2
    757     */
    758    public static <E> E first(final Iterator<E> iterator) {
    759        return get(iterator, 0);
    760    }
    761
    762    /**
    763     * Applies the closure to each element of the provided iterator.
    764     *
    765     * @param <E> the element type
    766     * @param iterator  the iterator to use, may be null
    767     * @param closure  the closure to apply to each element, may not be null
    768     * @throws NullPointerException if closure is null
    769     * @since 4.1
    770     */
    771    public static <E> void forEach(final Iterator<E> iterator, final Closure<? super E> closure) {
    772        Objects.requireNonNull(closure, "closure");
    773        if (iterator != null) {
    774            while (iterator.hasNext()) {
    775                closure.accept(iterator.next());
    776            }
    777        }
    778    }
    779
    780    /**
    781     * Executes the given closure on each but the last element in the iterator.
    782     * <p>
    783     * If the input iterator is null no change is made.
    784     * </p>
    785     *
    786     * @param <E> the type of object the {@link Iterator} contains
    787     * @param iterator  the iterator to get the input from, may be null
    788     * @param closure  the closure to perform, may not be null
    789     * @return the last element in the iterator, or null if iterator is null or empty
    790     * @throws NullPointerException if closure is null
    791     * @since 4.1
    792     */
    793    public static <E> E forEachButLast(final Iterator<E> iterator, final Closure<? super E> closure) {
    794        Objects.requireNonNull(closure, "closure");
    795
    796        if (iterator != null) {
    797            while (iterator.hasNext()) {
    798                final E element = iterator.next();
    799                if (!iterator.hasNext()) {
    800                    return element;
    801                }
    802                closure.accept(element);
    803            }
    804        }
    805        return null;
    806    }
    807
    808    /**
    809     * Gets the {@code index}-th value in {@link Iterator}, throwing {@code IndexOutOfBoundsException} if there is no such element.
    810     * <p>
    811     * The Iterator is advanced to {@code index} (or to the end, if {@code index} exceeds the number of entries) as a side effect of this method.
    812     * </p>
    813     *
    814     * @param <E>      the type of object in the {@link Iterator}.
    815     * @param iterator the iterator to get a value from.
    816     * @param index    the index to get, 0-based.
    817     * @return the object at the specified index.
    818     * @throws IndexOutOfBoundsException if the index is invalid.
    819     * @since 4.1
    820     */
    821    public static <E> E get(final Iterator<E> iterator, final int index) {
    822        return get(iterator, index, ioob -> {
    823            throw new IndexOutOfBoundsException("Entry does not exist: " + ioob);
    824        });
    825    }
    826
    827    /**
    828     * Gets the {@code index}-th value in {@link Iterator}, throwing {@code IndexOutOfBoundsException} if there is no such element.
    829     * <p>
    830     * The Iterator is advanced to {@code index} (or to the end, if {@code index} exceeds the number of entries) as a side effect of this method.
    831     * </p>
    832     *
    833     * @param <E>             the type of object in the {@link Iterator}
    834     * @param iterator        the iterator to get a value from
    835     * @param index           the index to get, 0-based.
    836     * @param defaultSupplier supplies a default value at an index.
    837     * @return the object at the specified index
    838     * @throws IndexOutOfBoundsException if the index is invalid
    839     */
    840    static <E> E get(final Iterator<E> iterator, final int index, final IntFunction<E> defaultSupplier) {
    841        int i = index;
    842        CollectionUtils.checkIndexBounds(i);
    843        while (iterator.hasNext()) {
    844            i--;
    845            if (i == -1) {
    846                return iterator.next();
    847            }
    848            iterator.next();
    849        }
    850        return defaultSupplier.apply(i);
    851    }
    852
    853    /**
    854     * Gets a suitable Iterator for the given object.
    855     * <p>
    856     * This method can handle objects as follows
    857     * </p>
    858     * <ul>
    859     * <li>null - empty iterator
    860     * <li>Iterator - returned directly
    861     * <li>Enumeration - wrapped
    862     * <li>Collection - iterator from collection returned
    863     * <li>Map - values iterator returned
    864     * <li>Dictionary - values (elements) enumeration returned as iterator
    865     * <li>array - iterator over array returned
    866     * <li>object with iterator() public method accessed by reflection
    867     * <li>object - singleton iterator
    868     * <li>NodeList - iterator over the list
    869     * <li>Node - iterator over the child nodes
    870     * </ul>
    871     *
    872     * @param obj  the object to convert to an iterator
    873     * @return a suitable iterator, never null
    874     */
    875    public static Iterator<?> getIterator(final Object obj) {
    876        if (obj == null) {
    877            return emptyIterator();
    878        }
    879        if (obj instanceof Iterator) {
    880            return (Iterator<?>) obj;
    881        }
    882        if (obj instanceof Iterable) {
    883            return ((Iterable<?>) obj).iterator();
    884        }
    885        if (obj instanceof Object[]) {
    886            return new ObjectArrayIterator<>((Object[]) obj);
    887        }
    888        if (obj instanceof Enumeration) {
    889            return new EnumerationIterator<>((Enumeration<?>) obj);
    890        }
    891        if (obj instanceof Map) {
    892            return ((Map<?, ?>) obj).values().iterator();
    893        }
    894        if (obj instanceof NodeList) {
    895            return new NodeListIterator((NodeList) obj);
    896        }
    897        if (obj instanceof Node) {
    898            return new NodeListIterator((Node) obj);
    899        }
    900        if (obj instanceof Dictionary) {
    901            return new EnumerationIterator<>(((Dictionary<?, ?>) obj).elements());
    902        }
    903        if (obj.getClass().isArray()) {
    904            return new ArrayIterator<>(obj);
    905        }
    906        try {
    907            final Method method = obj.getClass().getMethod("iterator", (Class[]) null);
    908            if (Iterator.class.isAssignableFrom(method.getReturnType())) {
    909                final Iterator<?> it = (Iterator<?>) method.invoke(obj, (Object[]) null);
    910                if (it != null) {
    911                    return it;
    912                }
    913            }
    914        } catch (final RuntimeException | ReflectiveOperationException ignore) { // NOPMD
    915            // ignore
    916        }
    917        return singletonIterator(obj);
    918    }
    919
    920    /**
    921     * Returns the index of the first element in the specified iterator that
    922     * matches the given predicate.
    923     * <p>
    924     * A {@code null} or empty iterator returns -1.
    925     * </p>
    926     *
    927     * @param <E> the element type
    928     * @param iterator  the iterator to search, may be null
    929     * @param predicate  the predicate to use, may not be null
    930     * @return the index of the first element which matches the predicate or -1 if none matches
    931     * @throws NullPointerException if predicate is null
    932     * @since 4.1
    933     */
    934    public static <E> int indexOf(final Iterator<E> iterator, final Predicate<? super E> predicate) {
    935        Objects.requireNonNull(predicate, "predicate");
    936
    937        if (iterator != null) {
    938            for (int index = 0; iterator.hasNext(); index++) {
    939                final E element = iterator.next();
    940                if (predicate.test(element)) {
    941                    return index;
    942                }
    943            }
    944        }
    945        return CollectionUtils.INDEX_NOT_FOUND;
    946    }
    947
    948    /**
    949     * Checks if the given iterator is empty.
    950     * <p>
    951     * A {@code null} or empty iterator returns true.
    952     * </p>
    953     *
    954     * @param iterator  the {@link Iterator} to use, may be null
    955     * @return true if the iterator is exhausted or null, false otherwise
    956     * @since 4.1
    957     */
    958    public static boolean isEmpty(final Iterator<?> iterator) {
    959        return iterator == null || !iterator.hasNext();
    960    }
    961
    962    /**
    963     * Gets an iterator that loops continuously over the supplied collection.
    964     * <p>
    965     * The iterator will only stop looping if the remove method is called
    966     * enough times to empty the collection, or if the collection is empty
    967     * to start with.
    968     * </p>
    969     *
    970     * @param <E> the element type
    971     * @param collection  the collection to iterate over, not null
    972     * @return a new looping iterator
    973     * @throws NullPointerException if the collection is null
    974     */
    975    public static <E> ResettableIterator<E> loopingIterator(final Collection<? extends E> collection) {
    976        return new LoopingIterator<>(Objects.requireNonNull(collection, "collection"));
    977    }
    978
    979    /**
    980     * Gets an iterator that loops continuously over the supplied list.
    981     * <p>
    982     * The iterator will only stop looping if the remove method is called
    983     * enough times to empty the list, or if the list is empty to start with.
    984     * </p>
    985     *
    986     * @param <E> the element type
    987     * @param list  the list to iterate over, not null
    988     * @return a new looping iterator
    989     * @throws NullPointerException if the list is null
    990     * @since 3.2
    991     */
    992    public static <E> ResettableListIterator<E> loopingListIterator(final List<E> list) {
    993        return new LoopingListIterator<>(Objects.requireNonNull(list, "list"));
    994    }
    995
    996    /**
    997     * Answers true if a predicate is true for every element of an iterator.
    998     * <p>
    999     * A {@code null} or empty iterator returns true.
    1000     * </p>
    1001     *
    1002     * @param <E> the type of object the {@link Iterator} contains
    1003     * @param iterator  the {@link Iterator} to use, may be null
    1004     * @param predicate  the predicate to use, may not be null
    1005     * @return true if every element of the collection matches the predicate or if the
    1006     *   collection is empty, false otherwise
    1007     * @throws NullPointerException if predicate is null
    1008     * @since 4.1
    1009     */
    1010    public static <E> boolean matchesAll(final Iterator<E> iterator, final Predicate<? super E> predicate) {
    1011        Objects.requireNonNull(predicate, "predicate");
    1012
    1013        if (iterator != null) {
    1014            while (iterator.hasNext()) {
    1015                final E element = iterator.next();
    1016                if (!predicate.test(element)) {
    1017                    return false;
    1018                }
    1019            }
    1020        }
    1021        return true;
    1022    }
    1023
    1024    /**
    1025     * Answers true if a predicate is true for any element of the iterator.
    1026     * <p>
    1027     * A {@code null} or empty iterator returns false.
    1028     * </p>
    1029     *
    1030     * @param <E> the type of object the {@link Iterator} contains
    1031     * @param iterator  the {@link Iterator} to use, may be null
    1032     * @param predicate  the predicate to use, may not be null
    1033     * @return true if any element of the collection matches the predicate, false otherwise
    1034     * @throws NullPointerException if predicate is null
    1035     * @since 4.1
    1036     */
    1037    public static <E> boolean matchesAny(final Iterator<E> iterator, final Predicate<? super E> predicate) {
    1038        return indexOf(iterator, predicate) != -1;
    1039    }
    1040
    1041    /**
    1042     * Gets an {@link Iterator} that wraps the specified node's childNodes.
    1043     * The returned {@link Iterator} can be used for a single iteration.
    1044     * <p>
    1045     * Convenience method, allows easy iteration over NodeLists:
    1046     * </p>
    1047     * <pre>
    1048     *   Iterator&lt;Node&gt; iterator = IteratorUtils.nodeListIterator(node);
    1049     *   for (Node childNode : IteratorUtils.asIterable(iterator)) {
    1050     *     ...
    1051     *   }
    1052     * </pre>
    1053     *
    1054     * @param node  the node to use, may not be null
    1055     * @return a new, single use {@link Iterator}
    1056     * @throws NullPointerException if node is null
    1057     * @since 4.0
    1058     */
    1059    public static NodeListIterator nodeListIterator(final Node node) {
    1060        return new NodeListIterator(Objects.requireNonNull(node, "node"));
    1061    }
    1062
    1063    /**
    1064     * Gets an {@link Iterator} that wraps the specified {@link NodeList}.
    1065     * The returned {@link Iterator} can be used for a single iteration.
    1066     *
    1067     * @param nodeList  the node list to use, may not be null
    1068     * @return a new, single use {@link Iterator}
    1069     * @throws NullPointerException if nodeList is null
    1070     * @since 4.0
    1071     */
    1072    public static NodeListIterator nodeListIterator(final NodeList nodeList) {
    1073        return new NodeListIterator(Objects.requireNonNull(nodeList, "nodeList"));
    1074    }
    1075
    1076    /**
    1077     * Gets an iterator that operates over an object graph.
    1078     * <p>
    1079     * This iterator can extract multiple objects from a complex tree-like object graph.
    1080     * The iteration starts from a single root object.
    1081     * It uses a {@code Transformer} to extract the iterators and elements.
    1082     * Its main benefit is that no intermediate {@code List} is created.
    1083     * </p>
    1084     * <p>
    1085     * For example, consider an object graph:
    1086     * </p>
    1087     * <pre>
    1088     *                 |- Branch -- Leaf
    1089     *                 |         \- Leaf
    1090     *         |- Tree |         /- Leaf
    1091     *         |       |- Branch -- Leaf
    1092     *  Forest |                 \- Leaf
    1093     *         |       |- Branch -- Leaf
    1094     *         |       |         \- Leaf
    1095     *         |- Tree |         /- Leaf
    1096     *                 |- Branch -- Leaf
    1097     *                 |- Branch -- Leaf</pre>
    1098     * <p>
    1099     * The following {@code Transformer}, used in this class, will extract all
    1100     * the Leaf objects without creating a combined intermediate list:
    1101     * </p>
    1102     * <pre>
    1103     * public Object transform(Object input) {
    1104     *   if (input instanceof Forest) {
    1105     *     return ((Forest) input).treeIterator();
    1106     *   }
    1107     *   if (input instanceof Tree) {
    1108     *     return ((Tree) input).branchIterator();
    1109     *   }
    1110     *   if (input instanceof Branch) {
    1111     *     return ((Branch) input).leafIterator();
    1112     *   }
    1113     *   if (input instanceof Leaf) {
    1114     *     return input;
    1115     *   }
    1116     *   throw new ClassCastException();
    1117     * }</pre>
    1118     * <p>
    1119     * Internally, iteration starts from the root object. When next is called,
    1120     * the transformer is called to examine the object. The transformer will return
    1121     * either an iterator or an object. If the object is an Iterator, the next element
    1122     * from that iterator is obtained and the process repeats. If the element is an object
    1123     * it is returned.
    1124     * </p>
    1125     * <p>
    1126     * Under many circumstances, linking Iterators together in this manner is
    1127     * more efficient (and convenient) than using nested for loops to extract a list.
    1128     * </p>
    1129     *
    1130     * @param <E> the element type
    1131     * @param root  the root object to start iterating from, null results in an empty iterator
    1132     * @param transformer  the transformer to use, see above, null uses no effect transformer
    1133     * @return a new object graph iterator
    1134     * @since 3.1
    1135     */
    1136    public static <E> Iterator<E> objectGraphIterator(final E root,
    1137            final Transformer<? super E, ? extends E> transformer) {
    1138        return new ObjectGraphIterator<>(root, transformer);
    1139    }
    1140
    1141    /**
    1142     * Gets an iterator that supports one-element lookahead.
    1143     *
    1144     * @param <E> the element type
    1145     * @param iterator  the iterator to decorate, not null
    1146     * @return a peeking iterator
    1147     * @throws NullPointerException if the iterator is null
    1148     * @since 4.0
    1149     */
    1150    public static <E> Iterator<E> peekingIterator(final Iterator<? extends E> iterator) {
    1151        return PeekingIterator.peekingIterator(iterator);
    1152    }
    1153
    1154    /**
    1155     * Gets an iterator that supports pushback of elements.
    1156     *
    1157     * @param <E> the element type
    1158     * @param iterator  the iterator to decorate, not null
    1159     * @return a pushback iterator
    1160     * @throws NullPointerException if the iterator is null
    1161     * @since 4.0
    1162     */
    1163    public static <E> Iterator<E> pushbackIterator(final Iterator<? extends E> iterator) {
    1164        return PushbackIterator.pushbackIterator(iterator);
    1165    }
    1166
    1167    /**
    1168     * Gets a singleton iterator.
    1169     * <p>
    1170     * This iterator is a valid iterator object that will iterate over
    1171     * the specified object.
    1172     * </p>
    1173     *
    1174     * @param <E> the element type
    1175     * @param object  the single object over which to iterate
    1176     * @return a singleton iterator over the object
    1177     */
    1178    public static <E> ResettableIterator<E> singletonIterator(final E object) {
    1179        return new SingletonIterator<>(object);
    1180    }
    1181
    1182    /**
    1183     * Gets a singleton list iterator.
    1184     * <p>
    1185     * This iterator is a valid list iterator object that will iterate over
    1186     * the specified object.
    1187     * </p>
    1188     *
    1189     * @param <E> the element type
    1190     * @param object  the single object over which to iterate
    1191     * @return a singleton list iterator over the object
    1192     */
    1193    public static <E> ListIterator<E> singletonListIterator(final E object) {
    1194        return new SingletonListIterator<>(object);
    1195    }
    1196
    1197    /**
    1198     * Returns the number of elements contained in the given iterator.
    1199     * <p>
    1200     * A {@code null} or empty iterator returns {@code 0}.
    1201     * </p>
    1202     *
    1203     * @param iterator  the iterator to check, may be null
    1204     * @return the number of elements contained in the iterator
    1205     * @since 4.1
    1206     */
    1207    public static int size(final Iterator<?> iterator) {
    1208        int size = 0;
    1209        if (iterator != null) {
    1210            while (iterator.hasNext()) {
    1211                iterator.next();
    1212                size++;
    1213            }
    1214        }
    1215        return size;
    1216    }
    1217
    1218    /**
    1219     * Decorates the specified iterator to skip the first N elements.
    1220     *
    1221     * @param <E> the element type
    1222     * @param iterator  the iterator to decorate
    1223     * @param offset  the first number of elements to skip
    1224     * @return a new skipping iterator
    1225     * @throws NullPointerException if the iterator is null
    1226     * @throws IllegalArgumentException if offset is negative
    1227     * @since 4.1
    1228     */
    1229    public static <E> SkippingIterator<E> skippingIterator(final Iterator<E> iterator, final long offset) {
    1230        return new SkippingIterator<>(iterator, offset);
    1231    }
    1232
    1233    /**
    1234     * Creates a stream on the given Iterable.
    1235     *
    1236     * @param <E> the type of elements in the Iterable.
    1237     * @param iterable the Iterable to stream or null.
    1238     * @return a new Stream or {@link Stream#empty()} if the Iterable is null.
    1239     * @since 4.5.0-M3
    1240     */
    1241    public static <E> Stream<E> stream(final Iterable<E> iterable) {
    1242        return iterable == null ? Stream.empty() : StreamSupport.stream(iterable.spliterator(), false);
    1243    }
    1244
    1245    /**
    1246     * Creates a stream on the given Iterator.
    1247     *
    1248     * @param <E> the type of elements in the Iterator.
    1249     * @param iterator the Iterator to stream or null.
    1250     * @return a new Stream or {@link Stream#empty()} if the Iterator is null.
    1251     * @since 4.5.0-M3
    1252     */
    1253    public static <E> Stream<E> stream(final Iterator<E> iterator) {
    1254        return iterator == null ? Stream.empty() : StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false);
    1255    }
    1256
    1257    /**
    1258     * Gets an array based on an iterator.
    1259     * <p>
    1260     * As the wrapped Iterator is traversed, an ArrayList of its values is
    1261     * created. At the end, this is converted to an array.
    1262     * </p>
    1263     *
    1264     * @param iterator  the iterator to use, not null
    1265     * @return an array of the iterator contents
    1266     * @throws NullPointerException if iterator parameter is null
    1267     */
    1268    public static Object[] toArray(final Iterator<?> iterator) {
    1269        Objects.requireNonNull(iterator, "iterator");
    1270        final List<?> list = toList(iterator, 100);
    1271        return list.toArray();
    1272    }
    1273
    1274    /**
    1275     * Gets an array based on an iterator.
    1276     * <p>
    1277     * As the wrapped Iterator is traversed, an ArrayList of its values is
    1278     * created. At the end, this is converted to an array.
    1279     * </p>
    1280     *
    1281     * @param <E> the element type
    1282     * @param iterator  the iterator to use, not null
    1283     * @param arrayClass  the class of array to create
    1284     * @return an array of the iterator contents
    1285     * @throws NullPointerException if iterator parameter or arrayClass is null
    1286     * @throws ArrayStoreException if the arrayClass is invalid
    1287     */
    1288    public static <E> E[] toArray(final Iterator<? extends E> iterator, final Class<E> arrayClass) {
    1289        Objects.requireNonNull(iterator, "iterator");
    1290        Objects.requireNonNull(arrayClass, "arrayClass");
    1291        final List<E> list = toList(iterator, 100);
    1292        @SuppressWarnings("unchecked")
    1293        final E[] array = (E[]) Array.newInstance(arrayClass, list.size());
    1294        return list.toArray(array);
    1295    }
    1296
    1297    /**
    1298     * Gets a list based on an iterator.
    1299     * <p>
    1300     * As the wrapped Iterator is traversed, an ArrayList of its values is
    1301     * created. At the end, the list is returned.
    1302     * </p>
    1303     *
    1304     * @param <E> the element type
    1305     * @param iterator  the iterator to use, not null
    1306     * @return a list of the iterator contents
    1307     * @throws NullPointerException if iterator parameter is null
    1308     */
    1309    public static <E> List<E> toList(final Iterator<? extends E> iterator) {
    1310        return toList(iterator, 10);
    1311    }
    1312
    1313    /**
    1314     * Gets a list based on an iterator.
    1315     * <p>
    1316     * As the wrapped Iterator is traversed, an ArrayList of its values is
    1317     * created. At the end, the list is returned.
    1318     * </p>
    1319     *
    1320     * @param <E> the element type
    1321     * @param iterator  the iterator to use, not null
    1322     * @param estimatedSize  the initial size of the ArrayList
    1323     * @return a list of the iterator contents
    1324     * @throws NullPointerException if iterator parameter is null
    1325     * @throws IllegalArgumentException if the size is less than 1
    1326     */
    1327    public static <E> List<E> toList(final Iterator<? extends E> iterator, final int estimatedSize) {
    1328        Objects.requireNonNull(iterator, "iterator");
    1329        if (estimatedSize < 1) {
    1330            throw new IllegalArgumentException("Estimated size must be greater than 0");
    1331        }
    1332        final List<E> list = new ArrayList<>(estimatedSize);
    1333        while (iterator.hasNext()) {
    1334            list.add(iterator.next());
    1335        }
    1336        return list;
    1337    }
    1338
    1339    /**
    1340     * Gets a list iterator based on a simple iterator.
    1341     * <p>
    1342     * As the wrapped Iterator is traversed, a LinkedList of its values is
    1343     * cached, permitting all required operations of ListIterator.
    1344     * </p>
    1345     *
    1346     * @param <E> the element type
    1347     * @param iterator  the iterator to use, may not be null
    1348     * @return a new iterator
    1349     * @throws NullPointerException if iterator parameter is null
    1350     */
    1351    public static <E> ListIterator<E> toListIterator(final Iterator<? extends E> iterator) {
    1352        Objects.requireNonNull(iterator, "iterator");
    1353        return new ListIteratorWrapper<>(iterator);
    1354    }
    1355
    1356    /**
    1357     * Returns a string representation of the elements of the specified iterator.
    1358     * <p>
    1359     * The string representation consists of a list of the iterator's elements,
    1360     * enclosed in square brackets ({@code "[]"}). Adjacent elements are separated
    1361     * by the characters {@code ", "} (a comma followed by a space). Elements are
    1362     * converted to strings as by {@code String.valueOf(Object)}.
    1363     * </p>
    1364     *
    1365     * @param <E> the element type
    1366     * @param iterator  the iterator to convert to a string, may be null
    1367     * @return a string representation of {@code iterator}
    1368     * @since 4.1
    1369     */
    1370    public static <E> String toString(final Iterator<E> iterator) {
    1371        return toString(iterator, TransformerUtils.stringValueTransformer(),
    1372                        DEFAULT_TOSTRING_DELIMITER, CollectionUtils.DEFAULT_TOSTRING_PREFIX,
    1373                CollectionUtils.DEFAULT_TOSTRING_SUFFIX);
    1374    }
    1375
    1376    /**
    1377     * Returns a string representation of the elements of the specified iterator.
    1378     * <p>
    1379     * The string representation consists of a list of the iterable's elements,
    1380     * enclosed in square brackets ({@code "[]"}). Adjacent elements are separated
    1381     * by the characters {@code ", "} (a comma followed by a space). Elements are
    1382     * converted to strings as by using the provided {@code transformer}.
    1383     * </p>
    1384     *
    1385     * @param <E> the element type
    1386     * @param iterator  the iterator to convert to a string, may be null
    1387     * @param transformer  the transformer used to get a string representation of an element
    1388     * @return a string representation of {@code iterator}
    1389     * @throws NullPointerException if {@code transformer} is null
    1390     * @since 4.1
    1391     */
    1392    public static <E> String toString(final Iterator<E> iterator,
    1393                                      final Transformer<? super E, String> transformer) {
    1394        return toString(iterator, transformer, DEFAULT_TOSTRING_DELIMITER,
    1395                CollectionUtils.DEFAULT_TOSTRING_PREFIX, CollectionUtils.DEFAULT_TOSTRING_SUFFIX);
    1396    }
    1397
    1398    /**
    1399     * Returns a string representation of the elements of the specified iterator.
    1400     * <p>
    1401     * The string representation consists of a list of the iterator's elements,
    1402     * enclosed by the provided {@code prefix} and {@code suffix}. Adjacent elements
    1403     * are separated by the provided {@code delimiter}. Elements are converted to
    1404     * strings as by using the provided {@code transformer}.
    1405     * </p>
    1406     *
    1407     * @param <E> the element type
    1408     * @param iterator  the iterator to convert to a string, may be null
    1409     * @param transformer  the transformer used to get a string representation of an element
    1410     * @param delimiter  the string to delimit elements
    1411     * @param prefix  the prefix, prepended to the string representation
    1412     * @param suffix  the suffix, appended to the string representation
    1413     * @return a string representation of {@code iterator}
    1414     * @throws NullPointerException if either transformer, delimiter, prefix or suffix is null
    1415     * @since 4.1
    1416     */
    1417    public static <E> String toString(final Iterator<E> iterator,
    1418                                      final Transformer<? super E, String> transformer,
    1419                                      final String delimiter,
    1420                                      final String prefix,
    1421                                      final String suffix) {
    1422        Objects.requireNonNull(transformer, "transformer");
    1423        Objects.requireNonNull(delimiter, "delimiter");
    1424        Objects.requireNonNull(prefix, "prefix");
    1425        Objects.requireNonNull(suffix, "suffix");
    1426        final StringBuilder stringBuilder = new StringBuilder(prefix);
    1427        if (iterator != null) {
    1428            while (iterator.hasNext()) {
    1429                final E element = iterator.next();
    1430                stringBuilder.append(transformer.apply(element));
    1431                stringBuilder.append(delimiter);
    1432            }
    1433            if (stringBuilder.length() > prefix.length()) {
    1434                stringBuilder.setLength(stringBuilder.length() - delimiter.length());
    1435            }
    1436        }
    1437        stringBuilder.append(suffix);
    1438        return stringBuilder.toString();
    1439    }
    1440
    1441    /**
    1442     * Gets an iterator that transforms the elements of another iterator.
    1443     * <p>
    1444     * The transformation occurs during the next() method and the underlying
    1445     * iterator is unaffected by the transformation.
    1446     * </p>
    1447     *
    1448     * @param <I> the input type
    1449     * @param <O> the output type
    1450     * @param iterator  the iterator to use, not null
    1451     * @param transformer  the transform to use, not null
    1452     * @return a new transforming iterator
    1453     * @throws NullPointerException if either parameter is null
    1454     */
    1455    public static <I, O> Iterator<O> transformedIterator(final Iterator<? extends I> iterator,
    1456            final Transformer<? super I, ? extends O> transformer) {
    1457
    1458        Objects.requireNonNull(iterator, "iterator");
    1459        Objects.requireNonNull(transformer, "transformer");
    1460        return new TransformIterator<>(iterator, transformer);
    1461    }
    1462
    1463    /**
    1464     * Gets an immutable version of an {@link Iterator}. The returned object
    1465     * will always throw an {@link UnsupportedOperationException} for
    1466     * the {@link Iterator#remove} method.
    1467     *
    1468     * @param <E> the element type
    1469     * @param iterator  the iterator to make immutable
    1470     * @return an immutable version of the iterator
    1471     */
    1472    public static <E> Iterator<E> unmodifiableIterator(final Iterator<E> iterator) {
    1473        return UnmodifiableIterator.unmodifiableIterator(iterator);
    1474    }
    1475
    1476    /**
    1477     * Gets an immutable version of a {@link ListIterator}. The returned object
    1478     * will always throw an {@link UnsupportedOperationException} for
    1479     * the {@link Iterator#remove}, {@link ListIterator#add} and
    1480     * {@link ListIterator#set} methods.
    1481     *
    1482     * @param <E> the element type
    1483     * @param listIterator  the iterator to make immutable
    1484     * @return an immutable version of the iterator
    1485     */
    1486    public static <E> ListIterator<E> unmodifiableListIterator(final ListIterator<E> listIterator) {
    1487        return UnmodifiableListIterator.unmodifiableListIterator(listIterator);
    1488    }
    1489
    1490    /**
    1491     * Gets an immutable version of a {@link MapIterator}. The returned object
    1492     * will always throw an {@link UnsupportedOperationException} for
    1493     * the {@link Iterator#remove}, {@link MapIterator#setValue(Object)} methods.
    1494     *
    1495     * @param <K> the key type
    1496     * @param <V> the value type
    1497     * @param mapIterator  the iterator to make immutable
    1498     * @return an immutable version of the iterator
    1499     */
    1500    public static <K, V> MapIterator<K, V> unmodifiableMapIterator(final MapIterator<K, V> mapIterator) {
    1501        return UnmodifiableMapIterator.unmodifiableMapIterator(mapIterator);
    1502    }
    1503
    1504    /**
    1505     * Returns an iterator that interleaves elements from the decorated iterators.
    1506     *
    1507     * @param <E> the element type
    1508     * @param iterators  the array of iterators to interleave
    1509     * @return an iterator, interleaving the decorated iterators
    1510     * @throws NullPointerException if any iterator is null
    1511     * @since 4.1
    1512     */
    1513    public static <E> ZippingIterator<E> zippingIterator(final Iterator<? extends E>... iterators) {
    1514        return new ZippingIterator<>(iterators);
    1515    }
    1516
    1517    /**
    1518     * Returns an iterator that interleaves elements from the decorated iterators.
    1519     *
    1520     * @param <E> the element type
    1521     * @param a  the first iterator to interleave
    1522     * @param b  the second iterator to interleave
    1523     * @return an iterator, interleaving the decorated iterators
    1524     * @throws NullPointerException if any iterator is null
    1525     * @since 4.1
    1526     */
    1527    public static <E> ZippingIterator<E> zippingIterator(final Iterator<? extends E> a,
    1528                                                         final Iterator<? extends E> b) {
    1529        return new ZippingIterator<>(a, b);
    1530    }
    1531
    1532    /**
    1533     * Returns an iterator that interleaves elements from the decorated iterators.
    1534     *
    1535     * @param <E> the element type
    1536     * @param a  the first iterator to interleave
    1537     * @param b  the second iterator to interleave
    1538     * @param c  the third iterator to interleave
    1539     * @return an iterator, interleaving the decorated iterators
    1540     * @throws NullPointerException if any iterator is null
    1541     * @since 4.1
    1542     */
    1543    public static <E> ZippingIterator<E> zippingIterator(final Iterator<? extends E> a,
    1544                                                         final Iterator<? extends E> b,
    1545                                                         final Iterator<? extends E> c) {
    1546        return new ZippingIterator<>(a, b, c);
    1547    }
    1548
    1549    /**
    1550     * Don't allow instances.
    1551     */
    1552    private IteratorUtils() {
    1553        // empty
    1554    }
    1555
    1556}