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