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