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