IteratorUtils.java

  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. import java.lang.reflect.Array;
  19. import java.lang.reflect.Method;
  20. import java.util.ArrayList;
  21. import java.util.Collection;
  22. import java.util.Comparator;
  23. import java.util.Dictionary;
  24. import java.util.Enumeration;
  25. import java.util.HashSet;
  26. import java.util.Iterator;
  27. import java.util.List;
  28. import java.util.ListIterator;
  29. import java.util.Map;
  30. import java.util.Objects;
  31. import java.util.Set;
  32. import java.util.Spliterator;
  33. import java.util.Spliterators;
  34. import java.util.function.IntFunction;
  35. import java.util.stream.Stream;
  36. import java.util.stream.StreamSupport;

  37. import org.apache.commons.collections4.functors.EqualPredicate;
  38. import org.apache.commons.collections4.iterators.ArrayIterator;
  39. import org.apache.commons.collections4.iterators.ArrayListIterator;
  40. import org.apache.commons.collections4.iterators.BoundedIterator;
  41. import org.apache.commons.collections4.iterators.CollatingIterator;
  42. import org.apache.commons.collections4.iterators.EmptyIterator;
  43. import org.apache.commons.collections4.iterators.EmptyListIterator;
  44. import org.apache.commons.collections4.iterators.EmptyMapIterator;
  45. import org.apache.commons.collections4.iterators.EmptyOrderedIterator;
  46. import org.apache.commons.collections4.iterators.EmptyOrderedMapIterator;
  47. import org.apache.commons.collections4.iterators.EnumerationIterator;
  48. import org.apache.commons.collections4.iterators.FilterIterator;
  49. import org.apache.commons.collections4.iterators.FilterListIterator;
  50. import org.apache.commons.collections4.iterators.IteratorChain;
  51. import org.apache.commons.collections4.iterators.IteratorEnumeration;
  52. import org.apache.commons.collections4.iterators.IteratorIterable;
  53. import org.apache.commons.collections4.iterators.LazyIteratorChain;
  54. import org.apache.commons.collections4.iterators.ListIteratorWrapper;
  55. import org.apache.commons.collections4.iterators.LoopingIterator;
  56. import org.apache.commons.collections4.iterators.LoopingListIterator;
  57. import org.apache.commons.collections4.iterators.NodeListIterator;
  58. import org.apache.commons.collections4.iterators.ObjectArrayIterator;
  59. import org.apache.commons.collections4.iterators.ObjectArrayListIterator;
  60. import org.apache.commons.collections4.iterators.ObjectGraphIterator;
  61. import org.apache.commons.collections4.iterators.PeekingIterator;
  62. import org.apache.commons.collections4.iterators.PushbackIterator;
  63. import org.apache.commons.collections4.iterators.SingletonIterator;
  64. import org.apache.commons.collections4.iterators.SingletonListIterator;
  65. import org.apache.commons.collections4.iterators.SkippingIterator;
  66. import org.apache.commons.collections4.iterators.TransformIterator;
  67. import org.apache.commons.collections4.iterators.UnmodifiableIterator;
  68. import org.apache.commons.collections4.iterators.UnmodifiableListIterator;
  69. import org.apache.commons.collections4.iterators.UnmodifiableMapIterator;
  70. import org.apache.commons.collections4.iterators.ZippingIterator;
  71. import org.w3c.dom.Node;
  72. import org.w3c.dom.NodeList;

  73. /**
  74.  * Provides static utility methods and decorators for {@link Iterator}
  75.  * instances. The implementations are provided in the iterators subpackage.
  76.  *
  77.  * @since 2.1
  78.  */
  79. public class IteratorUtils {
  80.     // validation is done in this class in certain cases because the
  81.     // public classes allow invalid states

  82.     /**
  83.      * An iterator over no elements.
  84.      */
  85.     @SuppressWarnings("rawtypes")
  86.     public static final ResettableIterator EMPTY_ITERATOR = EmptyIterator.RESETTABLE_INSTANCE;

  87.     /**
  88.      * A list iterator over no elements.
  89.      */
  90.     @SuppressWarnings("rawtypes")
  91.     public static final ResettableListIterator EMPTY_LIST_ITERATOR = EmptyListIterator.RESETTABLE_INSTANCE;

  92.     /**
  93.      * An ordered iterator over no elements.
  94.      */
  95.     @SuppressWarnings("rawtypes")
  96.     public static final OrderedIterator EMPTY_ORDERED_ITERATOR = EmptyOrderedIterator.INSTANCE;

  97.     /**
  98.      * A map iterator over no elements.
  99.      */
  100.     @SuppressWarnings("rawtypes")
  101.     public static final MapIterator EMPTY_MAP_ITERATOR = EmptyMapIterator.INSTANCE;

  102.     /**
  103.      * An ordered map iterator over no elements.
  104.      */
  105.     @SuppressWarnings("rawtypes")
  106.     public static final OrderedMapIterator EMPTY_ORDERED_MAP_ITERATOR = EmptyOrderedMapIterator.INSTANCE;
  107.     /**
  108.      * Default delimiter used to delimit elements while converting an Iterator
  109.      * to its String representation.
  110.      */
  111.     private static final String DEFAULT_TOSTRING_DELIMITER = ", ";

  112.     private static <E, C extends Collection<E>> C addAll(final Iterator<? extends E> iterator, final C list) {
  113.         Objects.requireNonNull(iterator, "iterator");
  114.         while (iterator.hasNext()) {
  115.             list.add(iterator.next());
  116.         }
  117.         return list;
  118.     }

  119.     /**
  120.      * Gets an iterator over an object array.
  121.      *
  122.      * @param <E> the element type
  123.      * @param array  the array over which to iterate
  124.      * @return an iterator over the array
  125.      * @throws NullPointerException if array is null
  126.      */
  127.     public static <E> ResettableIterator<E> arrayIterator(final E... array) {
  128.         return new ObjectArrayIterator<>(array);
  129.     }

  130.     /**
  131.      * Gets an iterator over the end part of an object array.
  132.      *
  133.      * @param <E> the element type
  134.      * @param array  the array over which to iterate
  135.      * @param start  the index to start iterating at
  136.      * @return an iterator over part of the array
  137.      * @throws IndexOutOfBoundsException if start is less than zero or greater
  138.      *   than the length of the array
  139.      * @throws NullPointerException if array is null
  140.      */
  141.     public static <E> ResettableIterator<E> arrayIterator(final E[] array, final int start) {
  142.         return new ObjectArrayIterator<>(array, start);
  143.     }

  144.     /**
  145.      * Gets an iterator over part of an object array.
  146.      *
  147.      * @param <E> the element type
  148.      * @param array  the array over which to iterate
  149.      * @param start  the index to start iterating at
  150.      * @param end  the index to finish iterating at
  151.      * @return an iterator over part of the array
  152.      * @throws IndexOutOfBoundsException if array bounds are invalid
  153.      * @throws IllegalArgumentException if end is before start
  154.      * @throws NullPointerException if array is null
  155.      */
  156.     public static <E> ResettableIterator<E> arrayIterator(final E[] array, final int start, final int end) {
  157.         return new ObjectArrayIterator<>(array, start, end);
  158.     }

  159.     /**
  160.      * Gets an iterator over an object or primitive array.
  161.      * <p>
  162.      * This method will handle primitive arrays as well as object arrays.
  163.      * The primitives will be wrapped in the appropriate wrapper class.
  164.      * </p>
  165.      *
  166.      * @param <E> the element type
  167.      * @param array  the array over which to iterate
  168.      * @return an iterator over the array
  169.      * @throws IllegalArgumentException if the array is not an array
  170.      * @throws NullPointerException if array is null
  171.      */
  172.     public static <E> ResettableIterator<E> arrayIterator(final Object array) {
  173.         return new ArrayIterator<>(array);
  174.     }

  175.     /**
  176.      * Gets an iterator over the end part of an object or primitive array.
  177.      * <p>
  178.      * This method will handle primitive arrays as well as object arrays.
  179.      * The primitives will be wrapped in the appropriate wrapper class.
  180.      * </p>
  181.      *
  182.      * @param <E> the element type
  183.      * @param array  the array over which to iterate
  184.      * @param start  the index to start iterating at
  185.      * @return an iterator over part of the array
  186.      * @throws IllegalArgumentException if the array is not an array
  187.      * @throws IndexOutOfBoundsException if start is less than zero or greater
  188.      *   than the length of the array
  189.      * @throws NullPointerException if array is null
  190.      */
  191.     public static <E> ResettableIterator<E> arrayIterator(final Object array, final int start) {
  192.         return new ArrayIterator<>(array, start);
  193.     }

  194.     /**
  195.      * Gets an iterator over part of an object or primitive array.
  196.      * <p>
  197.      * This method will handle primitive arrays as well as object arrays.
  198.      * The primitives will be wrapped in the appropriate wrapper class.
  199.      * </p>
  200.      *
  201.      * @param <E> the element type
  202.      * @param array  the array over which to iterate
  203.      * @param start  the index to start iterating at
  204.      * @param end  the index to finish iterating at
  205.      * @return an iterator over part of the array
  206.      * @throws IllegalArgumentException if the array is not an array or end is before start
  207.      * @throws IndexOutOfBoundsException if array bounds are invalid
  208.      * @throws NullPointerException if array is null
  209.      */
  210.     public static <E> ResettableIterator<E> arrayIterator(final Object array, final int start, final int end) {
  211.         return new ArrayIterator<>(array, start, end);
  212.     }

  213.     /**
  214.      * Gets a list iterator over an object array.
  215.      *
  216.      * @param <E> the element type
  217.      * @param array  the array over which to iterate
  218.      * @return a list iterator over the array
  219.      * @throws NullPointerException if array is null
  220.      */
  221.     public static <E> ResettableListIterator<E> arrayListIterator(final E... array) {
  222.         return new ObjectArrayListIterator<>(array);
  223.     }

  224.     /**
  225.      * Gets a list iterator over the end part of an object array.
  226.      *
  227.      * @param <E> the element type
  228.      * @param array  the array over which to iterate
  229.      * @param start  the index to start iterating at
  230.      * @return a list iterator over part of the array
  231.      * @throws IndexOutOfBoundsException if start is less than zero
  232.      * @throws NullPointerException if array is null
  233.      */
  234.     public static <E> ResettableListIterator<E> arrayListIterator(final E[] array, final int start) {
  235.         return new ObjectArrayListIterator<>(array, start);
  236.     }

  237.     /**
  238.      * Gets a list iterator over part of an object array.
  239.      *
  240.      * @param <E> the element type
  241.      * @param array  the array over which to iterate
  242.      * @param start  the index to start iterating at
  243.      * @param end  the index to finish iterating at
  244.      * @return a list iterator over part of the array
  245.      * @throws IndexOutOfBoundsException if array bounds are invalid
  246.      * @throws IllegalArgumentException if end is before start
  247.      * @throws NullPointerException if array is null
  248.      */
  249.     public static <E> ResettableListIterator<E> arrayListIterator(final E[] array, final int start, final int end) {
  250.         return new ObjectArrayListIterator<>(array, start, end);
  251.     }

  252.     /**
  253.      * Gets a list iterator over an object or primitive array.
  254.      * <p>
  255.      * This method will handle primitive arrays as well as object arrays.
  256.      * The primitives will be wrapped in the appropriate wrapper class.
  257.      * </p>
  258.      *
  259.      * @param <E> the element type
  260.      * @param array  the array over which to iterate
  261.      * @return a list iterator over the array
  262.      * @throws IllegalArgumentException if the array is not an array
  263.      * @throws NullPointerException if array is null
  264.      */
  265.     public static <E> ResettableListIterator<E> arrayListIterator(final Object array) {
  266.         return new ArrayListIterator<>(array);
  267.     }

  268.     /**
  269.      * Gets a list iterator over the end part of an object or primitive array.
  270.      * <p>
  271.      * This method will handle primitive arrays as well as object arrays.
  272.      * The primitives will be wrapped in the appropriate wrapper class.
  273.      * </p>
  274.      *
  275.      * @param <E> the element type
  276.      * @param array  the array over which to iterate
  277.      * @param start  the index to start iterating at
  278.      * @return a list iterator over part of the array
  279.      * @throws IllegalArgumentException if the array is not an array
  280.      * @throws IndexOutOfBoundsException if start is less than zero
  281.      * @throws NullPointerException if array is null
  282.      */
  283.     public static <E> ResettableListIterator<E> arrayListIterator(final Object array, final int start) {
  284.         return new ArrayListIterator<>(array, start);
  285.     }

  286.     /**
  287.      * Gets a list iterator over part of an object or primitive array.
  288.      * <p>
  289.      * This method will handle primitive arrays as well as object arrays.
  290.      * The primitives will be wrapped in the appropriate wrapper class.
  291.      * </p>
  292.      *
  293.      * @param <E> the element type
  294.      * @param array  the array over which to iterate
  295.      * @param start  the index to start iterating at
  296.      * @param end  the index to finish iterating at
  297.      * @return a list iterator over part of the array
  298.      * @throws IllegalArgumentException if the array is not an array or end is before start
  299.      * @throws IndexOutOfBoundsException if array bounds are invalid
  300.      * @throws NullPointerException if array is null
  301.      */
  302.     public static <E> ResettableListIterator<E> arrayListIterator(final Object array, final int start, final int end) {
  303.         return new ArrayListIterator<>(array, start, end);
  304.     }

  305.     /**
  306.      * Gets an enumeration that wraps an iterator.
  307.      *
  308.      * @param <E> the element type
  309.      * @param iterator  the iterator to use, may not be null
  310.      * @return a new enumeration
  311.      * @throws NullPointerException if iterator is null
  312.      */
  313.     public static <E> Enumeration<E> asEnumeration(final Iterator<? extends E> iterator) {
  314.         return new IteratorEnumeration<>(Objects.requireNonNull(iterator, "iterator"));
  315.     }

  316.     /**
  317.      * Gets an {@link Iterable} that wraps an iterator.  The returned {@link Iterable} can be
  318.      * used for a single iteration.
  319.      *
  320.      * @param <E> the element type
  321.      * @param iterator  the iterator to use, may not be null
  322.      * @return a new, single use {@link Iterable}
  323.      * @throws NullPointerException if iterator is null
  324.      */
  325.     public static <E> Iterable<E> asIterable(final Iterator<? extends E> iterator) {
  326.         Objects.requireNonNull(iterator, "iterator");
  327.         return new IteratorIterable<>(iterator, false);
  328.     }

  329.     /**
  330.      * Gets an iterator that provides an iterator view of the given enumeration.
  331.      *
  332.      * @param <E> the element type
  333.      * @param enumeration  the enumeration to use, may not be null
  334.      * @return a new iterator
  335.      * @throws NullPointerException if enumeration is null
  336.      */
  337.     public static <E> Iterator<E> asIterator(final Enumeration<? extends E> enumeration) {
  338.         return new EnumerationIterator<>(Objects.requireNonNull(enumeration, "enumeration"));
  339.     }

  340.     /**
  341.      * Gets an iterator that provides an iterator view of the given enumeration
  342.      * that will remove elements from the specified collection.
  343.      *
  344.      * @param <E> the element type
  345.      * @param enumeration  the enumeration to use, may not be null
  346.      * @param removeCollection  the collection to remove elements from, may not be null
  347.      * @return a new iterator
  348.      * @throws NullPointerException if enumeration or removeCollection is null
  349.      */
  350.     public static <E> Iterator<E> asIterator(final Enumeration<? extends E> enumeration,
  351.                                              final Collection<? super E> removeCollection) {
  352.         return new EnumerationIterator<>(Objects.requireNonNull(enumeration, "enumeration"),
  353.                 Objects.requireNonNull(removeCollection, "removeCollection"));
  354.     }

  355.     /**
  356.      * Gets an iterable that wraps an iterator.  The returned iterable can be
  357.      * used for multiple iterations.
  358.      *
  359.      * @param <E> the element type
  360.      * @param iterator  the iterator to use, may not be null
  361.      * @return a new, multiple use iterable
  362.      * @throws NullPointerException if iterator is null
  363.      */
  364.     public static <E> Iterable<E> asMultipleUseIterable(final Iterator<? extends E> iterator) {
  365.         Objects.requireNonNull(iterator, "iterator");
  366.         return new IteratorIterable<>(iterator, true);
  367.     }

  368.     // Bounded
  369.     /**
  370.      * Decorates the specified iterator to return at most the given number
  371.      * of elements.
  372.      *
  373.      * @param <E> the element type
  374.      * @param iterator  the iterator to decorate
  375.      * @param max  the maximum number of elements returned by this iterator
  376.      * @return a new bounded iterator
  377.      * @throws NullPointerException if the iterator is null
  378.      * @throws IllegalArgumentException if max is negative
  379.      * @since 4.1
  380.      */
  381.     public static <E> BoundedIterator<E> boundedIterator(final Iterator<? extends E> iterator, final long max) {
  382.         return boundedIterator(iterator, 0, max);
  383.     }

  384.     /**
  385.      * Decorates the specified iterator to return at most the given number
  386.      * of elements, skipping all elements until the iterator reaches the
  387.      * position at {@code offset}.
  388.      * <p>
  389.      * The iterator is immediately advanced until it reaches the position at
  390.      * {@code offset}, incurring O(n) time.
  391.      * </p>
  392.      *
  393.      * @param <E> the element type
  394.      * @param iterator  the iterator to decorate
  395.      * @param offset  the index of the first element of the decorated iterator to return
  396.      * @param max  the maximum number of elements returned by this iterator
  397.      * @return a new bounded iterator
  398.      * @throws NullPointerException if the iterator is null
  399.      * @throws IllegalArgumentException if either offset or max is negative
  400.      * @since 4.1
  401.      */
  402.     public static <E> BoundedIterator<E> boundedIterator(final Iterator<? extends E> iterator,
  403.                                                          final long offset, final long max) {
  404.         return new BoundedIterator<>(iterator, offset, max);
  405.     }

  406.     /**
  407.      * Gets an iterator that iterates through a collections of {@link Iterator}s
  408.      * one after another.
  409.      *
  410.      * @param <E> the element type
  411.      * @param iterators  the iterators to use, not null or empty or contain nulls
  412.      * @return a combination iterator over the iterators
  413.      * @throws NullPointerException if iterators collection is null or contains a null
  414.      * @throws ClassCastException if the iterators collection contains the wrong object type
  415.      */
  416.     public static <E> Iterator<E> chainedIterator(final Collection<? extends Iterator<? extends E>> iterators) {
  417.         return new IteratorChain<>(iterators);
  418.     }

  419.     /**
  420.      * Gets an iterator that iterates through an array of {@link Iterator}s
  421.      * one after another.
  422.      *
  423.      * @param <E> the element type
  424.      * @param iterators  the iterators to use, not null or empty or contain nulls
  425.      * @return a combination iterator over the iterators
  426.      * @throws NullPointerException if iterators array is null or contains a null
  427.      */
  428.     public static <E> Iterator<E> chainedIterator(final Iterator<? extends E>... iterators) {
  429.         return new IteratorChain<>(iterators);
  430.     }

  431.     /**
  432.      * Gets an iterator that iterates through two {@link Iterator}s
  433.      * one after another.
  434.      *
  435.      * @param <E> the element type
  436.      * @param iterator1  the first iterator to use, not null
  437.      * @param iterator2  the second iterator to use, not null
  438.      * @return a combination iterator over the iterators
  439.      * @throws NullPointerException if either iterator is null
  440.      */
  441.     public static <E> Iterator<E> chainedIterator(final Iterator<? extends E> iterator1,
  442.                                                   final Iterator<? extends E> iterator2) {
  443.         // keep a version with two iterators to avoid the following warning in client code (Java 5 & 6)
  444.         // "A generic array of E is created for a varargs parameter"
  445.         return new IteratorChain<>(iterator1, iterator2);
  446.     }

  447.     /**
  448.      * Gets an iterator that iterates through an {@link Iterator} of Iterators one after another.
  449.      *
  450.      * @param <E>       the element type
  451.      * @param iterators the iterators to use, not null or empty or contain nulls
  452.      * @return a combination iterator over the iterators
  453.      * @throws NullPointerException if iterators collection is null or contains a null
  454.      * @throws ClassCastException   if the iterators collection contains the wrong object type
  455.      * @since 4.5.0-M3
  456.      */
  457.     public static <E> Iterator<E> chainedIterator(final Iterator<? extends Iterator<? extends E>> iterators) {
  458.         return new LazyIteratorChain<E>() {

  459.             @Override
  460.             protected Iterator<? extends E> nextIterator(final int count) {
  461.                 return iterators.hasNext() ? iterators.next() : null;
  462.             }

  463.         };
  464.     }

  465.     /**
  466.      * Gets an iterator that provides an ordered iteration over the elements
  467.      * contained in a collection of {@link Iterator}s.
  468.      * <p>
  469.      * Given two ordered {@link Iterator}s {@code A} and {@code B},
  470.      * the {@link Iterator#next()} method will return the lesser of
  471.      * {@code A.next()} and {@code B.next()} and so on.
  472.      * </p>
  473.      * <p>
  474.      * The comparator is optional. If null is specified then natural order is used.
  475.      * </p>
  476.      *
  477.      * @param <E> the element type
  478.      * @param comparator  the comparator to use, may be null for natural order
  479.      * @param iterators  the iterators to use, not null or empty or contain nulls
  480.      * @return a combination iterator over the iterators
  481.      * @throws NullPointerException if iterators collection is null or contains a null
  482.      * @throws ClassCastException if the iterators collection contains the wrong object type
  483.      */
  484.     public static <E> Iterator<E> collatedIterator(final Comparator<? super E> comparator,
  485.                                                    final Collection<Iterator<? extends E>> iterators) {
  486.         @SuppressWarnings("unchecked")
  487.         final Comparator<E> comp =
  488.             comparator == null ? ComparatorUtils.NATURAL_COMPARATOR : (Comparator<E>) comparator;
  489.         return new CollatingIterator<>(comp, iterators);
  490.     }

  491.     /**
  492.      * Gets an iterator that provides an ordered iteration over the elements
  493.      * contained in an array of {@link Iterator}s.
  494.      * <p>
  495.      * Given two ordered {@link Iterator}s {@code A} and {@code B},
  496.      * the {@link Iterator#next()} method will return the lesser of
  497.      * {@code A.next()} and {@code B.next()} and so on.
  498.      * </p>
  499.      * <p>
  500.      * The comparator is optional. If null is specified then natural order is used.
  501.      * </p>
  502.      *
  503.      * @param <E> the element type
  504.      * @param comparator  the comparator to use, may be null for natural order
  505.      * @param iterators  the iterators to use, not null or empty or contain nulls
  506.      * @return a combination iterator over the iterators
  507.      * @throws NullPointerException if iterators array is null or contains a null value
  508.      */
  509.     public static <E> Iterator<E> collatedIterator(final Comparator<? super E> comparator,
  510.                                                    final Iterator<? extends E>... iterators) {
  511.         @SuppressWarnings("unchecked")
  512.         final Comparator<E> comp =
  513.             comparator == null ? ComparatorUtils.NATURAL_COMPARATOR : (Comparator<E>) comparator;
  514.         return new CollatingIterator<>(comp, iterators);
  515.     }

  516.     /**
  517.      * Gets an iterator that provides an ordered iteration over the elements
  518.      * contained in a collection of ordered {@link Iterator}s.
  519.      * <p>
  520.      * Given two ordered {@link Iterator}s {@code A} and {@code B},
  521.      * the {@link Iterator#next()} method will return the lesser of
  522.      * {@code A.next()} and {@code B.next()}.
  523.      * </p>
  524.      * <p>
  525.      * The comparator is optional. If null is specified then natural order is used.
  526.      * </p>
  527.      *
  528.      * @param <E> the element type
  529.      * @param comparator  the comparator to use, may be null for natural order
  530.      * @param iterator1  the first iterators to use, not null
  531.      * @param iterator2  the first iterators to use, not null
  532.      * @return a combination iterator over the iterators
  533.      * @throws NullPointerException if either iterator is null
  534.      */
  535.     public static <E> Iterator<E> collatedIterator(final Comparator<? super E> comparator,
  536.                                                    final Iterator<? extends E> iterator1,
  537.                                                    final Iterator<? extends E> iterator2) {
  538.         @SuppressWarnings("unchecked")
  539.         final Comparator<E> comp =
  540.             comparator == null ? ComparatorUtils.NATURAL_COMPARATOR : (Comparator<E>) comparator;
  541.         return new CollatingIterator<>(comp, iterator1, iterator2);
  542.     }

  543.     /**
  544.      * Checks if the object is contained in the given iterator.
  545.      * <p>
  546.      * A {@code null} or empty iterator returns false.
  547.      * </p>
  548.      *
  549.      * @param <E> the type of object the {@link Iterator} contains
  550.      * @param iterator  the iterator to check, may be null
  551.      * @param object  the object to check
  552.      * @return true if the object is contained in the iterator, false otherwise
  553.      * @since 4.1
  554.      */
  555.     public static <E> boolean contains(final Iterator<E> iterator, final Object object) {
  556.         return matchesAny(iterator, EqualPredicate.equalPredicate(object));
  557.     }

  558.     /**
  559.      * Gets an empty iterator.
  560.      * <p>
  561.      * This iterator is a valid iterator object that will iterate over nothing.
  562.      * </p>
  563.      *
  564.      * @param <E> the element type
  565.      * @return an iterator over nothing
  566.      */
  567.     public static <E> ResettableIterator<E> emptyIterator() {
  568.         return EmptyIterator.<E>resettableEmptyIterator();
  569.     }

  570.     /**
  571.      * Gets an empty list iterator.
  572.      * <p>
  573.      * This iterator is a valid list iterator object that will iterate
  574.      * over nothing.
  575.      * </p>
  576.      *
  577.      * @param <E> the element type
  578.      * @return a list iterator over nothing
  579.      */
  580.     public static <E> ResettableListIterator<E> emptyListIterator() {
  581.         return EmptyListIterator.<E>resettableEmptyListIterator();
  582.     }

  583.     /**
  584.      * Gets an empty map iterator.
  585.      * <p>
  586.      * This iterator is a valid map iterator object that will iterate
  587.      * over nothing.
  588.      * </p>
  589.      *
  590.      * @param <K> the key type
  591.      * @param <V> the value type
  592.      * @return a map iterator over nothing
  593.      */
  594.     public static <K, V> MapIterator<K, V> emptyMapIterator() {
  595.         return EmptyMapIterator.<K, V>emptyMapIterator();
  596.     }

  597.     /**
  598.      * Gets an empty ordered iterator.
  599.      * <p>
  600.      * This iterator is a valid iterator object that will iterate
  601.      * over nothing.
  602.      * </p>
  603.      *
  604.      * @param <E> the element type
  605.      * @return an ordered iterator over nothing
  606.      */
  607.     public static <E> OrderedIterator<E> emptyOrderedIterator() {
  608.         return EmptyOrderedIterator.<E>emptyOrderedIterator();
  609.     }

  610.     /**
  611.      * Gets an empty ordered map iterator.
  612.      * <p>
  613.      * This iterator is a valid map iterator object that will iterate
  614.      * over nothing.
  615.      * </p>
  616.      *
  617.      * @param <K> the key type
  618.      * @param <V> the value type
  619.      * @return a map iterator over nothing
  620.      */
  621.     public static <K, V> OrderedMapIterator<K, V> emptyOrderedMapIterator() {
  622.         return EmptyOrderedMapIterator.<K, V>emptyOrderedMapIterator();
  623.     }

  624.     /**
  625.      * Gets an iterator that filters another iterator.
  626.      * <p>
  627.      * The returned iterator will only return objects that match the specified
  628.      * filtering predicate.
  629.      * </p>
  630.      *
  631.      * @param <E> the element type
  632.      * @param iterator  the iterator to use, not null
  633.      * @param predicate  the predicate to use as a filter, not null
  634.      * @return a new filtered iterator
  635.      * @throws NullPointerException if either parameter is null
  636.      */
  637.     public static <E> Iterator<E> filteredIterator(final Iterator<? extends E> iterator,
  638.                                                    final Predicate<? super E> predicate) {
  639.         Objects.requireNonNull(iterator, "iterator");
  640.         Objects.requireNonNull(predicate, "predicate");
  641.         return new FilterIterator<>(iterator, predicate);
  642.     }

  643.     /**
  644.      * Gets a list iterator that filters another list iterator.
  645.      * <p>
  646.      * The returned iterator will only return objects that match the specified
  647.      * filtering predicate.
  648.      * </p>
  649.      *
  650.      * @param <E> the element type
  651.      * @param listIterator  the list iterator to use, not null
  652.      * @param predicate  the predicate to use as a filter, not null
  653.      * @return a new filtered iterator
  654.      * @throws NullPointerException if either parameter is null
  655.      */
  656.     public static <E> ListIterator<E> filteredListIterator(final ListIterator<? extends E> listIterator,
  657.             final Predicate<? super E> predicate) {

  658.         Objects.requireNonNull(listIterator, "listIterator");
  659.         Objects.requireNonNull(predicate, "predicate");
  660.         return new FilterListIterator<>(listIterator, predicate);
  661.     }

  662.     /**
  663.      * Finds the first element in the given iterator which matches the given predicate.
  664.      * <p>
  665.      * A {@code null} or empty iterator returns null.
  666.      * </p>
  667.      *
  668.      * @param <E> the element type
  669.      * @param iterator  the iterator to search, may be null
  670.      * @param predicate  the predicate to use, must not be null
  671.      * @return the first element of the iterator which matches the predicate or null if none could be found
  672.      * @throws NullPointerException if predicate is null
  673.      * @since 4.1
  674.      */
  675.     public static <E> E find(final Iterator<E> iterator, final Predicate<? super E> predicate) {
  676.         return find(iterator, predicate, null);
  677.     }

  678.     /**
  679.      * Finds the first element in the given iterator which matches the given predicate.
  680.      * <p>
  681.      * A {@code null} or empty iterator returns {@code defaultValue}.
  682.      * </p>
  683.      *
  684.      * @param <E>          the element type.
  685.      * @param iterator     the iterator to search, may be null.
  686.      * @param predicate    the predicate to use, must not be null.
  687.      * @param defaultValue the default value, may be null.
  688.      * @return the first element of the iterator which matches the predicate or null if none could be found.
  689.      * @throws NullPointerException if predicate is null.
  690.      */
  691.     private static <E> E find(final Iterator<E> iterator, final Predicate<? super E> predicate, final E defaultValue) {
  692.         Objects.requireNonNull(predicate, "predicate");
  693.         if (iterator != null) {
  694.             while (iterator.hasNext()) {
  695.                 final E element = iterator.next();
  696.                 if (predicate.test(element)) {
  697.                     return element;
  698.                 }
  699.             }
  700.         }
  701.         return defaultValue;
  702.     }

  703.     /**
  704.      * Shortcut for {@code get(iterator, 0)}.
  705.      * <p>
  706.      * Returns the {@code first} value in {@link Iterator}, throwing
  707.      * {@code IndexOutOfBoundsException} if there is no such element.
  708.      * </p>
  709.      * <p>
  710.      * The Iterator is advanced to {@code 0} (or to the end, if
  711.      * {@code 0} exceeds the number of entries) as a side effect of this method.
  712.      * </p>
  713.      * @param <E> the type of object in the {@link Iterator}
  714.      * @param iterator the iterator to get a value from
  715.      * @return the first object
  716.      * @throws IndexOutOfBoundsException if the request is invalid
  717.      * @since 4.2
  718.      */
  719.     public static <E> E first(final Iterator<E> iterator) {
  720.         return get(iterator, 0);
  721.     }

  722.     /**
  723.      * Applies the closure to each element of the provided iterator.
  724.      *
  725.      * @param <E> the element type
  726.      * @param iterator  the iterator to use, may be null
  727.      * @param closure  the closure to apply to each element, may not be null
  728.      * @throws NullPointerException if closure is null
  729.      * @since 4.1
  730.      */
  731.     public static <E> void forEach(final Iterator<E> iterator, final Closure<? super E> closure) {
  732.         Objects.requireNonNull(closure, "closure");
  733.         if (iterator != null) {
  734.             while (iterator.hasNext()) {
  735.                 closure.accept(iterator.next());
  736.             }
  737.         }
  738.     }

  739.     /**
  740.      * Executes the given closure on each but the last element in the iterator.
  741.      * <p>
  742.      * If the input iterator is null no change is made.
  743.      * </p>
  744.      *
  745.      * @param <E> the type of object the {@link Iterator} contains
  746.      * @param iterator  the iterator to get the input from, may be null
  747.      * @param closure  the closure to perform, may not be null
  748.      * @return the last element in the iterator, or null if iterator is null or empty
  749.      * @throws NullPointerException if closure is null
  750.      * @since 4.1
  751.      */
  752.     public static <E> E forEachButLast(final Iterator<E> iterator, final Closure<? super E> closure) {
  753.         Objects.requireNonNull(closure, "closure");

  754.         if (iterator != null) {
  755.             while (iterator.hasNext()) {
  756.                 final E element = iterator.next();
  757.                 if (!iterator.hasNext()) {
  758.                     return element;
  759.                 }
  760.                 closure.accept(element);
  761.             }
  762.         }
  763.         return null;
  764.     }

  765.     /**
  766.      * Gets the {@code index}-th value in {@link Iterator}, throwing {@code IndexOutOfBoundsException} if there is no such element.
  767.      * <p>
  768.      * 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.
  769.      * </p>
  770.      *
  771.      * @param <E>      the type of object in the {@link Iterator}.
  772.      * @param iterator the iterator to get a value from.
  773.      * @param index    the index to get, 0-based.
  774.      * @return the object at the specified index.
  775.      * @throws IndexOutOfBoundsException if the index is invalid.
  776.      * @since 4.1
  777.      */
  778.     public static <E> E get(final Iterator<E> iterator, final int index) {
  779.         return get(iterator, index, ioob -> {
  780.             throw new IndexOutOfBoundsException("Entry does not exist: " + ioob);
  781.         });
  782.     }

  783.     /**
  784.      * Gets the {@code index}-th value in {@link Iterator}, throwing {@code IndexOutOfBoundsException} if there is no such element.
  785.      * <p>
  786.      * 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.
  787.      * </p>
  788.      *
  789.      * @param <E>             the type of object in the {@link Iterator}
  790.      * @param iterator        the iterator to get a value from
  791.      * @param index           the index to get, 0-based.
  792.      * @param defaultSupplier supplies a default value at an index.
  793.      * @return the object at the specified index
  794.      * @throws IndexOutOfBoundsException if the index is invalid
  795.      */
  796.     static <E> E get(final Iterator<E> iterator, final int index, final IntFunction<E> defaultSupplier) {
  797.         int i = index;
  798.         CollectionUtils.checkIndexBounds(i);
  799.         while (iterator.hasNext()) {
  800.             i--;
  801.             if (i == -1) {
  802.                 return iterator.next();
  803.             }
  804.             iterator.next();
  805.         }
  806.         return defaultSupplier.apply(i);
  807.     }

  808.     /**
  809.      * Gets a suitable Iterator for the given object.
  810.      * <p>
  811.      * This method can handle objects as follows
  812.      * </p>
  813.      * <ul>
  814.      * <li>null - empty iterator
  815.      * <li>Iterator - returned directly
  816.      * <li>Enumeration - wrapped
  817.      * <li>Collection - iterator from collection returned
  818.      * <li>Map - values iterator returned
  819.      * <li>Dictionary - values (elements) enumeration returned as iterator
  820.      * <li>array - iterator over array returned
  821.      * <li>object with iterator() public method accessed by reflection
  822.      * <li>object - singleton iterator
  823.      * <li>NodeList - iterator over the list
  824.      * <li>Node - iterator over the child nodes
  825.      * </ul>
  826.      *
  827.      * @param obj  the object to convert to an iterator
  828.      * @return a suitable iterator, never null
  829.      */
  830.     public static Iterator<?> getIterator(final Object obj) {
  831.         if (obj == null) {
  832.             return emptyIterator();
  833.         }
  834.         if (obj instanceof Iterator) {
  835.             return (Iterator<?>) obj;
  836.         }
  837.         if (obj instanceof Iterable) {
  838.             return ((Iterable<?>) obj).iterator();
  839.         }
  840.         if (obj instanceof Object[]) {
  841.             return new ObjectArrayIterator<>((Object[]) obj);
  842.         }
  843.         if (obj instanceof Enumeration) {
  844.             return new EnumerationIterator<>((Enumeration<?>) obj);
  845.         }
  846.         if (obj instanceof Map) {
  847.             return ((Map<?, ?>) obj).values().iterator();
  848.         }
  849.         if (obj instanceof NodeList) {
  850.             return new NodeListIterator((NodeList) obj);
  851.         }
  852.         if (obj instanceof Node) {
  853.             return new NodeListIterator((Node) obj);
  854.         }
  855.         if (obj instanceof Dictionary) {
  856.             return new EnumerationIterator<>(((Dictionary<?, ?>) obj).elements());
  857.         }
  858.         if (obj.getClass().isArray()) {
  859.             return new ArrayIterator<>(obj);
  860.         }
  861.         try {
  862.             final Method method = obj.getClass().getMethod("iterator", (Class[]) null);
  863.             if (Iterator.class.isAssignableFrom(method.getReturnType())) {
  864.                 final Iterator<?> it = (Iterator<?>) method.invoke(obj, (Object[]) null);
  865.                 if (it != null) {
  866.                     return it;
  867.                 }
  868.             }
  869.         } catch (final RuntimeException | ReflectiveOperationException ignore) { // NOPMD
  870.             // ignore
  871.         }
  872.         return singletonIterator(obj);
  873.     }

  874.     /**
  875.      * Returns the index of the first element in the specified iterator that
  876.      * matches the given predicate.
  877.      * <p>
  878.      * A {@code null} or empty iterator returns -1.
  879.      * </p>
  880.      *
  881.      * @param <E> the element type
  882.      * @param iterator  the iterator to search, may be null
  883.      * @param predicate  the predicate to use, may not be null
  884.      * @return the index of the first element which matches the predicate or -1 if none matches
  885.      * @throws NullPointerException if predicate is null
  886.      * @since 4.1
  887.      */
  888.     public static <E> int indexOf(final Iterator<E> iterator, final Predicate<? super E> predicate) {
  889.         Objects.requireNonNull(predicate, "predicate");

  890.         if (iterator != null) {
  891.             for (int index = 0; iterator.hasNext(); index++) {
  892.                 final E element = iterator.next();
  893.                 if (predicate.test(element)) {
  894.                     return index;
  895.                 }
  896.             }
  897.         }
  898.         return CollectionUtils.INDEX_NOT_FOUND;
  899.     }

  900.     /**
  901.      * Checks if the given iterator is empty.
  902.      * <p>
  903.      * A {@code null} or empty iterator returns true.
  904.      * </p>
  905.      *
  906.      * @param iterator  the {@link Iterator} to use, may be null
  907.      * @return true if the iterator is exhausted or null, false otherwise
  908.      * @since 4.1
  909.      */
  910.     public static boolean isEmpty(final Iterator<?> iterator) {
  911.         return iterator == null || !iterator.hasNext();
  912.     }

  913.     /**
  914.      * Gets an iterator that loops continuously over the supplied collection.
  915.      * <p>
  916.      * The iterator will only stop looping if the remove method is called
  917.      * enough times to empty the collection, or if the collection is empty
  918.      * to start with.
  919.      * </p>
  920.      *
  921.      * @param <E> the element type
  922.      * @param collection  the collection to iterate over, not null
  923.      * @return a new looping iterator
  924.      * @throws NullPointerException if the collection is null
  925.      */
  926.     public static <E> ResettableIterator<E> loopingIterator(final Collection<? extends E> collection) {
  927.         return new LoopingIterator<>(Objects.requireNonNull(collection, "collection"));
  928.     }

  929.     /**
  930.      * Gets an iterator that loops continuously over the supplied list.
  931.      * <p>
  932.      * The iterator will only stop looping if the remove method is called
  933.      * enough times to empty the list, or if the list is empty to start with.
  934.      * </p>
  935.      *
  936.      * @param <E> the element type
  937.      * @param list  the list to iterate over, not null
  938.      * @return a new looping iterator
  939.      * @throws NullPointerException if the list is null
  940.      * @since 3.2
  941.      */
  942.     public static <E> ResettableListIterator<E> loopingListIterator(final List<E> list) {
  943.         return new LoopingListIterator<>(Objects.requireNonNull(list, "list"));
  944.     }

  945.     /**
  946.      * Answers true if a predicate is true for every element of an iterator.
  947.      * <p>
  948.      * A {@code null} or empty iterator returns true.
  949.      * </p>
  950.      *
  951.      * @param <E> the type of object the {@link Iterator} contains
  952.      * @param iterator  the {@link Iterator} to use, may be null
  953.      * @param predicate  the predicate to use, may not be null
  954.      * @return true if every element of the collection matches the predicate or if the
  955.      *   collection is empty, false otherwise
  956.      * @throws NullPointerException if predicate is null
  957.      * @since 4.1
  958.      */
  959.     public static <E> boolean matchesAll(final Iterator<E> iterator, final Predicate<? super E> predicate) {
  960.         Objects.requireNonNull(predicate, "predicate");

  961.         if (iterator != null) {
  962.             while (iterator.hasNext()) {
  963.                 final E element = iterator.next();
  964.                 if (!predicate.test(element)) {
  965.                     return false;
  966.                 }
  967.             }
  968.         }
  969.         return true;
  970.     }

  971.     /**
  972.      * Answers true if a predicate is true for any element of the iterator.
  973.      * <p>
  974.      * A {@code null} or empty iterator returns false.
  975.      * </p>
  976.      *
  977.      * @param <E> the type of object the {@link Iterator} contains
  978.      * @param iterator  the {@link Iterator} to use, may be null
  979.      * @param predicate  the predicate to use, may not be null
  980.      * @return true if any element of the collection matches the predicate, false otherwise
  981.      * @throws NullPointerException if predicate is null
  982.      * @since 4.1
  983.      */
  984.     public static <E> boolean matchesAny(final Iterator<E> iterator, final Predicate<? super E> predicate) {
  985.         return indexOf(iterator, predicate) != -1;
  986.     }

  987.     /**
  988.      * Gets an {@link Iterator} that wraps the specified node's childNodes.
  989.      * The returned {@link Iterator} can be used for a single iteration.
  990.      * <p>
  991.      * Convenience method, allows easy iteration over NodeLists:
  992.      * </p>
  993.      * <pre>
  994.      *   Iterator&lt;Node&gt; iterator = IteratorUtils.nodeListIterator(node);
  995.      *   for (Node childNode : IteratorUtils.asIterable(iterator)) {
  996.      *     ...
  997.      *   }
  998.      * </pre>
  999.      *
  1000.      * @param node  the node to use, may not be null
  1001.      * @return a new, single use {@link Iterator}
  1002.      * @throws NullPointerException if node is null
  1003.      * @since 4.0
  1004.      */
  1005.     public static NodeListIterator nodeListIterator(final Node node) {
  1006.         return new NodeListIterator(Objects.requireNonNull(node, "node"));
  1007.     }

  1008.     /**
  1009.      * Gets an {@link Iterator} that wraps the specified {@link NodeList}.
  1010.      * The returned {@link Iterator} can be used for a single iteration.
  1011.      *
  1012.      * @param nodeList  the node list to use, may not be null
  1013.      * @return a new, single use {@link Iterator}
  1014.      * @throws NullPointerException if nodeList is null
  1015.      * @since 4.0
  1016.      */
  1017.     public static NodeListIterator nodeListIterator(final NodeList nodeList) {
  1018.         return new NodeListIterator(Objects.requireNonNull(nodeList, "nodeList"));
  1019.     }

  1020.     /**
  1021.      * Gets an iterator that operates over an object graph.
  1022.      * <p>
  1023.      * This iterator can extract multiple objects from a complex tree-like object graph.
  1024.      * The iteration starts from a single root object.
  1025.      * It uses a {@code Transformer} to extract the iterators and elements.
  1026.      * Its main benefit is that no intermediate {@code List} is created.
  1027.      * </p>
  1028.      * <p>
  1029.      * For example, consider an object graph:
  1030.      * </p>
  1031.      * <pre>
  1032.      *                 |- Branch -- Leaf
  1033.      *                 |         \- Leaf
  1034.      *         |- Tree |         /- Leaf
  1035.      *         |       |- Branch -- Leaf
  1036.      *  Forest |                 \- Leaf
  1037.      *         |       |- Branch -- Leaf
  1038.      *         |       |         \- Leaf
  1039.      *         |- Tree |         /- Leaf
  1040.      *                 |- Branch -- Leaf
  1041.      *                 |- Branch -- Leaf</pre>
  1042.      * <p>
  1043.      * The following {@code Transformer}, used in this class, will extract all
  1044.      * the Leaf objects without creating a combined intermediate list:
  1045.      * </p>
  1046.      * <pre>
  1047.      * public Object transform(Object input) {
  1048.      *   if (input instanceof Forest) {
  1049.      *     return ((Forest) input).treeIterator();
  1050.      *   }
  1051.      *   if (input instanceof Tree) {
  1052.      *     return ((Tree) input).branchIterator();
  1053.      *   }
  1054.      *   if (input instanceof Branch) {
  1055.      *     return ((Branch) input).leafIterator();
  1056.      *   }
  1057.      *   if (input instanceof Leaf) {
  1058.      *     return input;
  1059.      *   }
  1060.      *   throw new ClassCastException();
  1061.      * }</pre>
  1062.      * <p>
  1063.      * Internally, iteration starts from the root object. When next is called,
  1064.      * the transformer is called to examine the object. The transformer will return
  1065.      * either an iterator or an object. If the object is an Iterator, the next element
  1066.      * from that iterator is obtained and the process repeats. If the element is an object
  1067.      * it is returned.
  1068.      * </p>
  1069.      * <p>
  1070.      * Under many circumstances, linking Iterators together in this manner is
  1071.      * more efficient (and convenient) than using nested for loops to extract a list.
  1072.      * </p>
  1073.      *
  1074.      * @param <E> the element type
  1075.      * @param root  the root object to start iterating from, null results in an empty iterator
  1076.      * @param transformer  the transformer to use, see above, null uses no effect transformer
  1077.      * @return a new object graph iterator
  1078.      * @since 3.1
  1079.      */
  1080.     public static <E> Iterator<E> objectGraphIterator(final E root,
  1081.             final Transformer<? super E, ? extends E> transformer) {
  1082.         return new ObjectGraphIterator<>(root, transformer);
  1083.     }

  1084.     /**
  1085.      * Gets an iterator that supports one-element lookahead.
  1086.      *
  1087.      * @param <E> the element type
  1088.      * @param iterator  the iterator to decorate, not null
  1089.      * @return a peeking iterator
  1090.      * @throws NullPointerException if the iterator is null
  1091.      * @since 4.0
  1092.      */
  1093.     public static <E> Iterator<E> peekingIterator(final Iterator<? extends E> iterator) {
  1094.         return PeekingIterator.peekingIterator(iterator);
  1095.     }

  1096.     /**
  1097.      * Gets an iterator that supports pushback of elements.
  1098.      *
  1099.      * @param <E> the element type
  1100.      * @param iterator  the iterator to decorate, not null
  1101.      * @return a pushback iterator
  1102.      * @throws NullPointerException if the iterator is null
  1103.      * @since 4.0
  1104.      */
  1105.     public static <E> Iterator<E> pushbackIterator(final Iterator<? extends E> iterator) {
  1106.         return PushbackIterator.pushbackIterator(iterator);
  1107.     }

  1108.     /**
  1109.      * Gets a singleton iterator.
  1110.      * <p>
  1111.      * This iterator is a valid iterator object that will iterate over
  1112.      * the specified object.
  1113.      * </p>
  1114.      *
  1115.      * @param <E> the element type
  1116.      * @param object  the single object over which to iterate
  1117.      * @return a singleton iterator over the object
  1118.      */
  1119.     public static <E> ResettableIterator<E> singletonIterator(final E object) {
  1120.         return new SingletonIterator<>(object);
  1121.     }

  1122.     /**
  1123.      * Gets a singleton list iterator.
  1124.      * <p>
  1125.      * This iterator is a valid list iterator object that will iterate over
  1126.      * 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 list iterator over the object
  1132.      */
  1133.     public static <E> ListIterator<E> singletonListIterator(final E object) {
  1134.         return new SingletonListIterator<>(object);
  1135.     }

  1136.     /**
  1137.      * Returns the number of elements contained in the given iterator.
  1138.      * <p>
  1139.      * A {@code null} or empty iterator returns {@code 0}.
  1140.      * </p>
  1141.      *
  1142.      * @param iterator  the iterator to check, may be null
  1143.      * @return the number of elements contained in the iterator
  1144.      * @since 4.1
  1145.      */
  1146.     public static int size(final Iterator<?> iterator) {
  1147.         int size = 0;
  1148.         if (iterator != null) {
  1149.             while (iterator.hasNext()) {
  1150.                 iterator.next();
  1151.                 size++;
  1152.             }
  1153.         }
  1154.         return size;
  1155.     }

  1156.     /**
  1157.      * Decorates the specified iterator to skip the first N elements.
  1158.      *
  1159.      * @param <E> the element type
  1160.      * @param iterator  the iterator to decorate
  1161.      * @param offset  the first number of elements to skip
  1162.      * @return a new skipping iterator
  1163.      * @throws NullPointerException if the iterator is null
  1164.      * @throws IllegalArgumentException if offset is negative
  1165.      * @since 4.1
  1166.      */
  1167.     public static <E> SkippingIterator<E> skippingIterator(final Iterator<E> iterator, final long offset) {
  1168.         return new SkippingIterator<>(iterator, offset);
  1169.     }

  1170.     /**
  1171.      * Creates a stream on the given Iterable.
  1172.      *
  1173.      * @param <E> the type of elements in the Iterable.
  1174.      * @param iterable the Iterable to stream or null.
  1175.      * @return a new Stream or {@link Stream#empty()} if the Iterable is null.
  1176.      * @since 4.5.0-M3
  1177.      */
  1178.     public static <E> Stream<E> stream(final Iterable<E> iterable) {
  1179.         return iterable == null ? Stream.empty() : StreamSupport.stream(iterable.spliterator(), false);
  1180.     }

  1181.     /**
  1182.      * Creates a stream on the given Iterator.
  1183.      *
  1184.      * @param <E> the type of elements in the Iterator.
  1185.      * @param iterator the Iterator to stream or null.
  1186.      * @return a new Stream or {@link Stream#empty()} if the Iterator is null.
  1187.      * @since 4.5.0-M3
  1188.      */
  1189.     public static <E> Stream<E> stream(final Iterator<E> iterator) {
  1190.         return iterator == null ? Stream.empty() : StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false);
  1191.     }

  1192.     /**
  1193.      * Gets an array based on an iterator.
  1194.      * <p>
  1195.      * As the wrapped Iterator is traversed, an ArrayList of its values is
  1196.      * created. At the end, this is converted to an array.
  1197.      * </p>
  1198.      *
  1199.      * @param iterator  the iterator to use, not null
  1200.      * @return an array of the iterator contents
  1201.      * @throws NullPointerException if iterator parameter is null
  1202.      */
  1203.     public static Object[] toArray(final Iterator<?> iterator) {
  1204.         Objects.requireNonNull(iterator, "iterator");
  1205.         final List<?> list = toList(iterator, 100);
  1206.         return list.toArray();
  1207.     }

  1208.     /**
  1209.      * Gets an array based on an iterator.
  1210.      * <p>
  1211.      * As the wrapped Iterator is traversed, an ArrayList of its values is
  1212.      * created. At the end, this is converted to an array.
  1213.      * </p>
  1214.      *
  1215.      * @param <E> the element type
  1216.      * @param iterator  the iterator to use, not null
  1217.      * @param arrayClass  the class of array to create
  1218.      * @return an array of the iterator contents
  1219.      * @throws NullPointerException if iterator parameter or arrayClass is null
  1220.      * @throws ArrayStoreException if the arrayClass is invalid
  1221.      */
  1222.     public static <E> E[] toArray(final Iterator<? extends E> iterator, final Class<E> arrayClass) {
  1223.         Objects.requireNonNull(iterator, "iterator");
  1224.         Objects.requireNonNull(arrayClass, "arrayClass");
  1225.         final List<E> list = toList(iterator, 100);
  1226.         @SuppressWarnings("unchecked")
  1227.         final E[] array = (E[]) Array.newInstance(arrayClass, list.size());
  1228.         return list.toArray(array);
  1229.     }

  1230.     /**
  1231.      * Gets a list based on an iterator.
  1232.      * <p>
  1233.      * As the wrapped Iterator is traversed, an ArrayList of its values is
  1234.      * created. At the end, the list is returned.
  1235.      * </p>
  1236.      *
  1237.      * @param <E> the element type
  1238.      * @param iterator  the iterator to use, not null
  1239.      * @return a list of the iterator contents
  1240.      * @throws NullPointerException if iterator parameter is null
  1241.      */
  1242.     public static <E> List<E> toList(final Iterator<? extends E> iterator) {
  1243.         return toList(iterator, 10);
  1244.     }

  1245.     /**
  1246.      * Gets a list based on an iterator.
  1247.      * <p>
  1248.      * As the wrapped Iterator is traversed, an ArrayList of its values is
  1249.      * created. At the end, the list is returned.
  1250.      * </p>
  1251.      *
  1252.      * @param <E> the element type
  1253.      * @param iterator  the iterator to use, not null
  1254.      * @param estimatedSize  the initial size of the ArrayList
  1255.      * @return a list of the iterator contents
  1256.      * @throws NullPointerException if iterator parameter is null
  1257.      * @throws IllegalArgumentException if the size is less than 1
  1258.      */
  1259.     public static <E> List<E> toList(final Iterator<? extends E> iterator, final int estimatedSize) {
  1260.         if (estimatedSize < 1) {
  1261.             throw new IllegalArgumentException("Estimated size must be greater than 0");
  1262.         }
  1263.         return addAll(iterator, new ArrayList<>(estimatedSize));
  1264.     }

  1265.     /**
  1266.      * Gets a list iterator based on a simple iterator.
  1267.      * <p>
  1268.      * As the wrapped Iterator is traversed, a LinkedList of its values is
  1269.      * cached, permitting all required operations of ListIterator.
  1270.      * </p>
  1271.      *
  1272.      * @param <E> the element type
  1273.      * @param iterator  the iterator to use, may not be null
  1274.      * @return a new iterator
  1275.      * @throws NullPointerException if iterator parameter is null
  1276.      */
  1277.     public static <E> ListIterator<E> toListIterator(final Iterator<? extends E> iterator) {
  1278.         Objects.requireNonNull(iterator, "iterator");
  1279.         return new ListIteratorWrapper<>(iterator);
  1280.     }

  1281.     /**
  1282.      * Gets a set based on an iterator.
  1283.      * <p>
  1284.      * As the wrapped Iterator is traversed, a HashSet of its values is
  1285.      * created. At the end, the set is returned.
  1286.      * </p>
  1287.      *
  1288.      * @param <E> the element type
  1289.      * @param iterator  the iterator to use, not null
  1290.      * @return a set of the iterator contents
  1291.      * @throws NullPointerException if iterator parameter is null
  1292.      * @since 4.5.0-M4
  1293.      */
  1294.     public static <E> Set<E> toSet(final Iterator<? extends E> iterator) {
  1295.         return toSet(iterator, 10);
  1296.     }

  1297.     /**
  1298.      * Gets a set based on an iterator.
  1299.      * <p>
  1300.      * As the wrapped Iterator is traversed, a HashSet of its values is
  1301.      * created. At the end, the set is returned.
  1302.      * </p>
  1303.      *
  1304.      * @param <E> the element type
  1305.      * @param iterator  the iterator to use, not null
  1306.      * @param estimatedSize  the initial size of the HashSet
  1307.      * @return a list of the iterator contents
  1308.      * @throws NullPointerException if iterator parameter is null
  1309.      * @throws IllegalArgumentException if the size is less than 1
  1310.      * @since 4.5.0-M4
  1311.      */
  1312.     public static <E> Set<E> toSet(final Iterator<? extends E> iterator, final int estimatedSize) {
  1313.         if (estimatedSize < 1) {
  1314.             throw new IllegalArgumentException("Estimated size must be greater than 0");
  1315.         }
  1316.         return addAll(iterator, new HashSet<>(estimatedSize));
  1317.     }

  1318.     /**
  1319.      * Returns a string representation of the elements of the specified iterator.
  1320.      * <p>
  1321.      * The string representation consists of a list of the iterator's elements,
  1322.      * enclosed in square brackets ({@code "[]"}). Adjacent elements are separated
  1323.      * by the characters {@code ", "} (a comma followed by a space). Elements are
  1324.      * converted to strings as by {@code String.valueOf(Object)}.
  1325.      * </p>
  1326.      *
  1327.      * @param <E> the element type
  1328.      * @param iterator  the iterator to convert to a string, may be null
  1329.      * @return a string representation of {@code iterator}
  1330.      * @since 4.1
  1331.      */
  1332.     public static <E> String toString(final Iterator<E> iterator) {
  1333.         return toString(iterator, TransformerUtils.stringValueTransformer(),
  1334.                         DEFAULT_TOSTRING_DELIMITER, CollectionUtils.DEFAULT_TOSTRING_PREFIX,
  1335.                 CollectionUtils.DEFAULT_TOSTRING_SUFFIX);
  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 iterable's elements,
  1341.      * enclosed in square brackets ({@code "[]"}). Adjacent elements are separated
  1342.      * by the characters {@code ", "} (a comma followed by a space). Elements are
  1343.      * converted to strings as by using the provided {@code transformer}.
  1344.      * </p>
  1345.      *
  1346.      * @param <E> the element type
  1347.      * @param iterator  the iterator to convert to a string, may be null
  1348.      * @param transformer  the transformer used to get a string representation of an element
  1349.      * @return a string representation of {@code iterator}
  1350.      * @throws NullPointerException if {@code transformer} is null
  1351.      * @since 4.1
  1352.      */
  1353.     public static <E> String toString(final Iterator<E> iterator,
  1354.                                       final Transformer<? super E, String> transformer) {
  1355.         return toString(iterator, transformer, DEFAULT_TOSTRING_DELIMITER,
  1356.                 CollectionUtils.DEFAULT_TOSTRING_PREFIX, CollectionUtils.DEFAULT_TOSTRING_SUFFIX);
  1357.     }

  1358.     /**
  1359.      * Returns a string representation of the elements of the specified iterator.
  1360.      * <p>
  1361.      * The string representation consists of a list of the iterator's elements,
  1362.      * enclosed by the provided {@code prefix} and {@code suffix}. Adjacent elements
  1363.      * are separated by the provided {@code delimiter}. Elements are converted to
  1364.      * strings as by using the provided {@code transformer}.
  1365.      * </p>
  1366.      *
  1367.      * @param <E> the element type
  1368.      * @param iterator  the iterator to convert to a string, may be null
  1369.      * @param transformer  the transformer used to get a string representation of an element
  1370.      * @param delimiter  the string to delimit elements
  1371.      * @param prefix  the prefix, prepended to the string representation
  1372.      * @param suffix  the suffix, appended to the string representation
  1373.      * @return a string representation of {@code iterator}
  1374.      * @throws NullPointerException if either transformer, delimiter, prefix or suffix is null
  1375.      * @since 4.1
  1376.      */
  1377.     public static <E> String toString(final Iterator<E> iterator,
  1378.                                       final Transformer<? super E, String> transformer,
  1379.                                       final String delimiter,
  1380.                                       final String prefix,
  1381.                                       final String suffix) {
  1382.         Objects.requireNonNull(transformer, "transformer");
  1383.         Objects.requireNonNull(delimiter, "delimiter");
  1384.         Objects.requireNonNull(prefix, "prefix");
  1385.         Objects.requireNonNull(suffix, "suffix");
  1386.         final StringBuilder stringBuilder = new StringBuilder(prefix);
  1387.         if (iterator != null) {
  1388.             while (iterator.hasNext()) {
  1389.                 final E element = iterator.next();
  1390.                 stringBuilder.append(transformer.apply(element));
  1391.                 stringBuilder.append(delimiter);
  1392.             }
  1393.             if (stringBuilder.length() > prefix.length()) {
  1394.                 stringBuilder.setLength(stringBuilder.length() - delimiter.length());
  1395.             }
  1396.         }
  1397.         stringBuilder.append(suffix);
  1398.         return stringBuilder.toString();
  1399.     }

  1400.     /**
  1401.      * Gets an iterator that transforms the elements of another iterator.
  1402.      * <p>
  1403.      * The transformation occurs during the next() method and the underlying
  1404.      * iterator is unaffected by the transformation.
  1405.      * </p>
  1406.      *
  1407.      * @param <I> the input type
  1408.      * @param <O> the output type
  1409.      * @param iterator  the iterator to use, not null
  1410.      * @param transformer  the transform to use, not null
  1411.      * @return a new transforming iterator
  1412.      * @throws NullPointerException if either parameter is null
  1413.      */
  1414.     public static <I, O> Iterator<O> transformedIterator(final Iterator<? extends I> iterator,
  1415.             final Transformer<? super I, ? extends O> transformer) {

  1416.         Objects.requireNonNull(iterator, "iterator");
  1417.         Objects.requireNonNull(transformer, "transformer");
  1418.         return new TransformIterator<>(iterator, transformer);
  1419.     }

  1420.     /**
  1421.      * Gets an immutable version of an {@link Iterator}. The returned object
  1422.      * will always throw an {@link UnsupportedOperationException} for
  1423.      * the {@link Iterator#remove} method.
  1424.      *
  1425.      * @param <E> the element type
  1426.      * @param iterator  the iterator to make immutable
  1427.      * @return an immutable version of the iterator
  1428.      */
  1429.     public static <E> Iterator<E> unmodifiableIterator(final Iterator<E> iterator) {
  1430.         return UnmodifiableIterator.unmodifiableIterator(iterator);
  1431.     }

  1432.     /**
  1433.      * Gets an immutable version of a {@link ListIterator}. The returned object
  1434.      * will always throw an {@link UnsupportedOperationException} for
  1435.      * the {@link Iterator#remove}, {@link ListIterator#add} and
  1436.      * {@link ListIterator#set} methods.
  1437.      *
  1438.      * @param <E> the element type
  1439.      * @param listIterator  the iterator to make immutable
  1440.      * @return an immutable version of the iterator
  1441.      */
  1442.     public static <E> ListIterator<E> unmodifiableListIterator(final ListIterator<E> listIterator) {
  1443.         return UnmodifiableListIterator.unmodifiableListIterator(listIterator);
  1444.     }

  1445.     /**
  1446.      * Gets an immutable version of a {@link MapIterator}. The returned object
  1447.      * will always throw an {@link UnsupportedOperationException} for
  1448.      * the {@link Iterator#remove}, {@link MapIterator#setValue(Object)} methods.
  1449.      *
  1450.      * @param <K> the key type
  1451.      * @param <V> the value type
  1452.      * @param mapIterator  the iterator to make immutable
  1453.      * @return an immutable version of the iterator
  1454.      */
  1455.     public static <K, V> MapIterator<K, V> unmodifiableMapIterator(final MapIterator<K, V> mapIterator) {
  1456.         return UnmodifiableMapIterator.unmodifiableMapIterator(mapIterator);
  1457.     }

  1458.     /**
  1459.      * Returns an iterator that interleaves elements from the decorated iterators.
  1460.      *
  1461.      * @param <E> the element type
  1462.      * @param iterators  the array of iterators to interleave
  1463.      * @return an iterator, interleaving the decorated iterators
  1464.      * @throws NullPointerException if any iterator is null
  1465.      * @since 4.1
  1466.      */
  1467.     public static <E> ZippingIterator<E> zippingIterator(final Iterator<? extends E>... iterators) {
  1468.         return new ZippingIterator<>(iterators);
  1469.     }

  1470.     /**
  1471.      * Returns an iterator that interleaves elements from the decorated iterators.
  1472.      *
  1473.      * @param <E> the element type
  1474.      * @param a  the first iterator to interleave
  1475.      * @param b  the second iterator to interleave
  1476.      * @return an iterator, interleaving the decorated iterators
  1477.      * @throws NullPointerException if any iterator is null
  1478.      * @since 4.1
  1479.      */
  1480.     public static <E> ZippingIterator<E> zippingIterator(final Iterator<? extends E> a,
  1481.                                                          final Iterator<? extends E> b) {
  1482.         return new ZippingIterator<>(a, b);
  1483.     }

  1484.     /**
  1485.      * Returns an iterator that interleaves elements from the decorated iterators.
  1486.      *
  1487.      * @param <E> the element type
  1488.      * @param a  the first iterator to interleave
  1489.      * @param b  the second iterator to interleave
  1490.      * @param c  the third iterator to interleave
  1491.      * @return an iterator, interleaving the decorated iterators
  1492.      * @throws NullPointerException if any iterator is null
  1493.      * @since 4.1
  1494.      */
  1495.     public static <E> ZippingIterator<E> zippingIterator(final Iterator<? extends E> a,
  1496.                                                          final Iterator<? extends E> b,
  1497.                                                          final Iterator<? extends E> c) {
  1498.         return new ZippingIterator<>(a, b, c);
  1499.     }

  1500.     /**
  1501.      * Don't allow instances.
  1502.      */
  1503.     private IteratorUtils() {
  1504.         // empty
  1505.     }

  1506. }