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<Node> 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 }