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