View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.collections4;
18  
19  import java.lang.reflect.Array;
20  import java.lang.reflect.Method;
21  import java.util.ArrayList;
22  import java.util.Collection;
23  import java.util.Comparator;
24  import java.util.Dictionary;
25  import java.util.Enumeration;
26  import java.util.HashSet;
27  import java.util.Iterator;
28  import java.util.List;
29  import java.util.ListIterator;
30  import java.util.Map;
31  import java.util.Objects;
32  import java.util.Set;
33  import java.util.Spliterator;
34  import java.util.Spliterators;
35  import java.util.function.IntFunction;
36  import java.util.stream.Stream;
37  import java.util.stream.StreamSupport;
38  
39  import org.apache.commons.collections4.functors.EqualPredicate;
40  import org.apache.commons.collections4.iterators.ArrayIterator;
41  import org.apache.commons.collections4.iterators.ArrayListIterator;
42  import org.apache.commons.collections4.iterators.BoundedIterator;
43  import org.apache.commons.collections4.iterators.CollatingIterator;
44  import org.apache.commons.collections4.iterators.EmptyIterator;
45  import org.apache.commons.collections4.iterators.EmptyListIterator;
46  import org.apache.commons.collections4.iterators.EmptyMapIterator;
47  import org.apache.commons.collections4.iterators.EmptyOrderedIterator;
48  import org.apache.commons.collections4.iterators.EmptyOrderedMapIterator;
49  import org.apache.commons.collections4.iterators.EnumerationIterator;
50  import org.apache.commons.collections4.iterators.FilterIterator;
51  import org.apache.commons.collections4.iterators.FilterListIterator;
52  import org.apache.commons.collections4.iterators.IteratorChain;
53  import org.apache.commons.collections4.iterators.IteratorEnumeration;
54  import org.apache.commons.collections4.iterators.IteratorIterable;
55  import org.apache.commons.collections4.iterators.LazyIteratorChain;
56  import org.apache.commons.collections4.iterators.ListIteratorWrapper;
57  import org.apache.commons.collections4.iterators.LoopingIterator;
58  import org.apache.commons.collections4.iterators.LoopingListIterator;
59  import org.apache.commons.collections4.iterators.NodeListIterator;
60  import org.apache.commons.collections4.iterators.ObjectArrayIterator;
61  import org.apache.commons.collections4.iterators.ObjectArrayListIterator;
62  import org.apache.commons.collections4.iterators.ObjectGraphIterator;
63  import org.apache.commons.collections4.iterators.PeekingIterator;
64  import org.apache.commons.collections4.iterators.PushbackIterator;
65  import org.apache.commons.collections4.iterators.SingletonIterator;
66  import org.apache.commons.collections4.iterators.SingletonListIterator;
67  import org.apache.commons.collections4.iterators.SkippingIterator;
68  import org.apache.commons.collections4.iterators.TransformIterator;
69  import org.apache.commons.collections4.iterators.UnmodifiableIterator;
70  import org.apache.commons.collections4.iterators.UnmodifiableListIterator;
71  import org.apache.commons.collections4.iterators.UnmodifiableMapIterator;
72  import org.apache.commons.collections4.iterators.ZippingIterator;
73  import org.w3c.dom.Node;
74  import org.w3c.dom.NodeList;
75  
76  /**
77   * Provides static utility methods and decorators for {@link Iterator}
78   * instances. The implementations are provided in the iterators subpackage.
79   *
80   * @since 2.1
81   */
82  public class IteratorUtils {
83      // validation is done in this class in certain cases because the
84      // public classes allow invalid states
85  
86      /**
87       * An iterator over no elements.
88       */
89      @SuppressWarnings("rawtypes")
90      public static final ResettableIterator EMPTY_ITERATOR = EmptyIterator.RESETTABLE_INSTANCE;
91  
92      /**
93       * A list iterator over no elements.
94       */
95      @SuppressWarnings("rawtypes")
96      public static final ResettableListIterator EMPTY_LIST_ITERATOR = EmptyListIterator.RESETTABLE_INSTANCE;
97  
98      /**
99       * 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 }