IterableUtils.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.util.ArrayList;
  19. import java.util.Collection;
  20. import java.util.Collections;
  21. import java.util.Comparator;
  22. import java.util.HashSet;
  23. import java.util.Iterator;
  24. import java.util.LinkedHashSet;
  25. import java.util.List;
  26. import java.util.Objects;
  27. import java.util.Set;

  28. import org.apache.commons.collections4.functors.EqualPredicate;
  29. import org.apache.commons.collections4.iterators.LazyIteratorChain;
  30. import org.apache.commons.collections4.iterators.ReverseListIterator;
  31. import org.apache.commons.collections4.iterators.UniqueFilterIterator;

  32. /**
  33.  * Provides utility methods and decorators for {@link Iterable} instances.
  34.  * <p>
  35.  * <strong>Note</strong>: This utility class has been designed with fail-fast argument checking.
  36.  * </p>
  37.  * <ul>
  38.  * <li>All decorator methods are <em>not</em> null-safe for the provided Iterable argument; for example, they will throw a {@link NullPointerException} if a
  39.  * null Iterable is passed as argument.
  40.  * <li>All other utility methods are null-safe for the provided Iterable argument; for example, they will treat a null Iterable the same way as an empty one.
  41.  * For other arguments which are null, a {@link Predicate} will result in a {@link NullPointerException}. Exception: passing a null {@link Comparator} is
  42.  * equivalent to a Comparator with natural ordering.
  43.  * </ul>
  44.  *
  45.  * @since 4.1
  46.  */
  47. public class IterableUtils {

  48.     /**
  49.      * Inner class to distinguish unmodifiable instances.
  50.      */
  51.     private static final class UnmodifiableIterable<E> extends FluentIterable<E> {
  52.         private final Iterable<E> iterable;

  53.         UnmodifiableIterable(final Iterable<E> iterable) {
  54.             this.iterable = iterable;
  55.         }

  56.         @Override
  57.         public Iterator<E> iterator() {
  58.             return IteratorUtils.unmodifiableIterator(iterable.iterator());
  59.         }
  60.     }

  61.     /**
  62.      * An empty iterable.
  63.      */
  64.     @SuppressWarnings("rawtypes")
  65.     static final FluentIterable EMPTY_ITERABLE = new FluentIterable<Object>() {
  66.         @Override
  67.         public Iterator<Object> iterator() {
  68.             return IteratorUtils.emptyIterator();
  69.         }
  70.     };

  71.     /**
  72.      * Returns a view of the given iterable that contains at most the given number
  73.      * of elements.
  74.      * <p>
  75.      * The returned iterable's iterator supports {@code remove()} when the corresponding
  76.      * input iterator supports it.
  77.      * </p>
  78.      *
  79.      * @param <E> the element type
  80.      * @param iterable  the iterable to limit, may not be null
  81.      * @param maxSize  the maximum number of elements, must not be negative
  82.      * @return a bounded view on the specified iterable
  83.      * @throws IllegalArgumentException if maxSize is negative
  84.      * @throws NullPointerException if iterable is null
  85.      */
  86.     public static <E> Iterable<E> boundedIterable(final Iterable<E> iterable, final long maxSize) {
  87.         Objects.requireNonNull(iterable, "iterable");
  88.         if (maxSize < 0) {
  89.             throw new IllegalArgumentException("MaxSize parameter must not be negative.");
  90.         }

  91.         return new FluentIterable<E>() {
  92.             @Override
  93.             public Iterator<E> iterator() {
  94.                 return IteratorUtils.boundedIterator(iterable.iterator(), maxSize);
  95.             }
  96.         };
  97.     }

  98.     /**
  99.      * Combines the provided iterables into a single iterable.
  100.      * <p>
  101.      * The returned iterable has an iterator that traverses the elements in the order
  102.      * of the arguments, i.e. iterables[0], iterables[1], .... The source iterators
  103.      * are not polled until necessary.
  104.      * </p>
  105.      * <p>
  106.      * The returned iterable's iterator supports {@code remove()} when the corresponding
  107.      * input iterator supports it.
  108.      * </p>
  109.      *
  110.      * @param <E> the element type
  111.      * @param iterables  the iterables to combine, may not be null
  112.      * @return a new iterable, combining the provided iterables
  113.      * @throws NullPointerException if either of the provided iterables is null
  114.      */
  115.     public static <E> Iterable<E> chainedIterable(final Iterable<? extends E>... iterables) {
  116.         checkNotNull(iterables);
  117.         return new FluentIterable<E>() {
  118.             @Override
  119.             public Iterator<E> iterator() {
  120.                 return new LazyIteratorChain<E>() {
  121.                     @Override
  122.                     protected Iterator<? extends E> nextIterator(final int count) {
  123.                         if (count > iterables.length) {
  124.                             return null;
  125.                         }
  126.                         return iterables[count - 1].iterator();
  127.                     }
  128.                 };
  129.             }
  130.         };
  131.     }

  132.     /**
  133.      * Combines two iterables into a single iterable.
  134.      * <p>
  135.      * The returned iterable has an iterator that traverses the elements in {@code a},
  136.      * followed by the elements in {@code b}. The source iterators are not polled until
  137.      * necessary.
  138.      * </p>
  139.      * <p>
  140.      * The returned iterable's iterator supports {@code remove()} when the corresponding
  141.      * input iterator supports it.
  142.      * </p>
  143.      *
  144.      * @param <E> the element type
  145.      * @param a  the first iterable, may not be null
  146.      * @param b  the second iterable, may not be null
  147.      * @return a new iterable, combining the provided iterables
  148.      * @throws NullPointerException if either a or b is null
  149.      */
  150.     @SuppressWarnings("unchecked")
  151.     public static <E> Iterable<E> chainedIterable(final Iterable<? extends E> a,
  152.                                                   final Iterable<? extends E> b) {
  153.         return chainedIterable(new Iterable[] {a, b});
  154.     }

  155.     /**
  156.      * Combines three iterables into a single iterable.
  157.      * <p>
  158.      * The returned iterable has an iterator that traverses the elements in {@code a},
  159.      * followed by the elements in {@code b} and {@code c}. The source iterators are
  160.      * not polled until necessary.
  161.      * </p>
  162.      * <p>
  163.      * The returned iterable's iterator supports {@code remove()} when the corresponding
  164.      * input iterator supports it.
  165.      * </p>
  166.      *
  167.      * @param <E> the element type
  168.      * @param a  the first iterable, may not be null
  169.      * @param b  the second iterable, may not be null
  170.      * @param c  the third iterable, may not be null
  171.      * @return a new iterable, combining the provided iterables
  172.      * @throws NullPointerException if either of the provided iterables is null
  173.      */
  174.     @SuppressWarnings("unchecked")
  175.     public static <E> Iterable<E> chainedIterable(final Iterable<? extends E> a,
  176.                                                   final Iterable<? extends E> b,
  177.                                                   final Iterable<? extends E> c) {
  178.         return chainedIterable(new Iterable[] {a, b, c});
  179.     }

  180.     /**
  181.      * Combines four iterables into a single iterable.
  182.      * <p>
  183.      * The returned iterable has an iterator that traverses the elements in {@code a},
  184.      * followed by the elements in {@code b}, {@code c} and {@code d}. The source
  185.      * iterators are not polled until necessary.
  186.      * </p>
  187.      * <p>
  188.      * The returned iterable's iterator supports {@code remove()} when the corresponding
  189.      * input iterator supports it.
  190.      * </p>
  191.      *
  192.      * @param <E> the element type
  193.      * @param a  the first iterable, may not be null
  194.      * @param b  the second iterable, may not be null
  195.      * @param c  the third iterable, may not be null
  196.      * @param d  the fourth iterable, may not be null
  197.      * @return a new iterable, combining the provided iterables
  198.      * @throws NullPointerException if either of the provided iterables is null
  199.      */
  200.     @SuppressWarnings("unchecked")
  201.     public static <E> Iterable<E> chainedIterable(final Iterable<? extends E> a,
  202.                                                   final Iterable<? extends E> b,
  203.                                                   final Iterable<? extends E> c,
  204.                                                   final Iterable<? extends E> d) {
  205.         return chainedIterable(new Iterable[] {a, b, c, d});
  206.     }

  207.     /**
  208.      * Fail-fast check for null arguments.
  209.      *
  210.      * @param iterables  the iterables to check
  211.      * @throws NullPointerException if the argument or any of its contents is null
  212.      */
  213.     static void checkNotNull(final Iterable<?>... iterables) {
  214.         Objects.requireNonNull(iterables, "iterables");
  215.         for (final Iterable<?> iterable : iterables) {
  216.             Objects.requireNonNull(iterable, "iterable");
  217.         }
  218.     }

  219.     /**
  220.      * Combines the two provided iterables into an ordered iterable using the
  221.      * provided comparator. If the comparator is null, natural ordering will be
  222.      * used.
  223.      * <p>
  224.      * The returned iterable's iterator supports {@code remove()} when the
  225.      * corresponding input iterator supports it.
  226.      * </p>
  227.      *
  228.      * @param <E> the element type
  229.      * @param comparator  the comparator defining an ordering over the elements,
  230.      *   may be null, in which case natural ordering will be used
  231.      * @param a  the first iterable, may not be null
  232.      * @param b  the second iterable, may not be null
  233.      * @return a filtered view on the specified iterable
  234.      * @throws NullPointerException if either of the provided iterables is null
  235.      */
  236.     public static <E> Iterable<E> collatedIterable(final Comparator<? super E> comparator,
  237.                                                    final Iterable<? extends E> a,
  238.                                                    final Iterable<? extends E> b) {
  239.         checkNotNull(a, b);
  240.         return new FluentIterable<E>() {
  241.             @Override
  242.             public Iterator<E> iterator() {
  243.                 return IteratorUtils.collatedIterator(comparator, a.iterator(), b.iterator());
  244.             }
  245.         };
  246.     }

  247.     /**
  248.      * Combines the two provided iterables into an ordered iterable using
  249.      * natural ordering.
  250.      * <p>
  251.      * The returned iterable's iterator supports {@code remove()} when the
  252.      * corresponding input iterator supports it.
  253.      * </p>
  254.      *
  255.      * @param <E> the element type
  256.      * @param a  the first iterable, must not be null
  257.      * @param b  the second iterable, must not be null
  258.      * @return a filtered view on the specified iterable
  259.      * @throws NullPointerException if either of the provided iterables is null
  260.      */
  261.     public static <E> Iterable<E> collatedIterable(final Iterable<? extends E> a,
  262.                                                    final Iterable<? extends E> b) {
  263.         checkNotNull(a, b);
  264.         return new FluentIterable<E>() {
  265.             @Override
  266.             public Iterator<E> iterator() {
  267.                 return IteratorUtils.collatedIterator(null, a.iterator(), b.iterator());
  268.             }
  269.         };
  270.     }

  271.     /**
  272.      * Checks if the object is contained in the given iterable. Object equality
  273.      * is tested with an {@code equator} unlike {@link #contains(Iterable, Object)}
  274.      * which uses {@link Object#equals(Object)}.
  275.      * <p>
  276.      * A {@code null} or empty iterable returns false.
  277.      * A {@code null} object will not be passed to the equator, instead a
  278.      * {@link org.apache.commons.collections4.functors.NullPredicate NullPredicate}
  279.      * will be used.
  280.      * </p>
  281.      *
  282.      * @param <E> the type of object the {@link Iterable} contains
  283.      * @param iterable  the iterable to check, may be null
  284.      * @param object  the object to check
  285.      * @param equator  the equator to use to check, may not be null
  286.      * @return true if the object is contained in the iterable, false otherwise
  287.      * @throws NullPointerException if equator is null
  288.      */
  289.     public static <E> boolean contains(final Iterable<? extends E> iterable, final E object,
  290.                                        final Equator<? super E> equator) {
  291.         Objects.requireNonNull(equator, "equator");
  292.         return matchesAny(iterable, EqualPredicate.equalPredicate(object, equator));
  293.     }

  294.     /**
  295.      * Checks if the object is contained in the given iterable.
  296.      * <p>
  297.      * A {@code null} or empty iterable returns false.
  298.      * </p>
  299.      *
  300.      * @param <E> the type of object the {@link Iterable} contains
  301.      * @param iterable  the iterable to check, may be null
  302.      * @param object  the object to check
  303.      * @return true if the object is contained in the iterable, false otherwise
  304.      */
  305.     public static <E> boolean contains(final Iterable<E> iterable, final Object object) {
  306.         if (iterable instanceof Collection<?>) {
  307.             return ((Collection<E>) iterable).contains(object);
  308.         }
  309.         return IteratorUtils.contains(emptyIteratorIfNull(iterable), object);
  310.     }

  311.     /**
  312.      * Counts the number of elements in the input iterable that match the predicate.
  313.      * <p>
  314.      * A {@code null} iterable matches no elements.
  315.      * </p>
  316.      *
  317.      * @param <E> the type of object the {@link Iterable} contains
  318.      * @param input  the {@link Iterable} to get the input from, may be null
  319.      * @param predicate  the predicate to use, may not be null
  320.      * @return the number of matches for the predicate in the collection
  321.      * @throws NullPointerException if predicate is null
  322.      */
  323.     public static <E> long countMatches(final Iterable<E> input, final Predicate<? super E> predicate) {
  324.         Objects.requireNonNull(predicate, "predicate");
  325.         return size(filteredIterable(emptyIfNull(input), predicate));
  326.     }

  327.     /**
  328.      * Finds and returns the List of duplicate elements in the given collection.
  329.      *
  330.      * @param <E> the type of elements in the collection.
  331.      * @param iterable the list to test, must not be null.
  332.      * @return the set of duplicate elements, may be empty.
  333.      * @since 4.5.0-M3
  334.      */
  335.     public static <E> List<E> duplicateList(final Iterable<E> iterable) {
  336.         return new ArrayList<>(duplicateSequencedSet(iterable));
  337.     }

  338.     /**
  339.      * Finds and returns the sequenced Set of duplicate elements in the given collection.
  340.      * <p>
  341.      * Once we are on Java 21 and a new major version, the return type should be SequencedSet.
  342.      * </p>
  343.      *
  344.      * @param <E> the type of elements in the collection.
  345.      * @param iterable the list to test, must not be null.
  346.      * @return the set of duplicate elements, may be empty.
  347.      * @since 4.5.0-M3
  348.      */
  349.     public static <E> Set<E> duplicateSequencedSet(final Iterable<E> iterable) {
  350.         return duplicateSet(iterable, new LinkedHashSet<>());
  351.     }

  352.     /**
  353.      * Finds and returns the set of duplicate elements in the given collection.
  354.      *
  355.      * @param <E> the type of elements in the collection.
  356.      * @param iterable the list to test, must not be null.
  357.      * @return the set of duplicate elements, may be empty.
  358.      * @since 4.5.0-M3
  359.      */
  360.     public static <E> Set<E> duplicateSet(final Iterable<E> iterable) {
  361.         return duplicateSet(iterable, new HashSet<>());
  362.     }

  363.     /**
  364.      * Worker method for {@link #duplicateSet(Collection)} and friends.
  365.      *
  366.      * @param <C> the type of Collection.
  367.      * @param <E> the type of elements in the Collection.
  368.      * @param iterable the list to test, must not be null.
  369.      * @param duplicates the list to test, must not be null.
  370.      * @return the set of duplicate elements, may be empty.
  371.      */
  372.     static <C extends Collection<E>, E> C duplicateSet(final Iterable<E> iterable, final C duplicates) {
  373.         final Set<E> set = new HashSet<>();
  374.         for (final E e : iterable) {
  375.             (set.contains(e) ? duplicates : set).add(e);
  376.         }
  377.         return duplicates;
  378.     }

  379.     /**
  380.      * Returns an immutable empty iterable if the argument is null,
  381.      * or the argument itself otherwise.
  382.      *
  383.      * @param <E> the element type
  384.      * @param iterable  the iterable, may be null
  385.      * @return an empty iterable if the argument is null
  386.      */
  387.     public static <E> Iterable<E> emptyIfNull(final Iterable<E> iterable) {
  388.         return iterable == null ? IterableUtils.<E>emptyIterable() : iterable;
  389.     }

  390.     /**
  391.      * Gets an empty iterable.
  392.      * <p>
  393.      * This iterable does not contain any elements.
  394.      * </p>
  395.      *
  396.      * @param <E> the element type
  397.      * @return an empty iterable
  398.      */
  399.     @SuppressWarnings("unchecked") // OK, empty collection is compatible with any type
  400.     public static <E> Iterable<E> emptyIterable() {
  401.         return EMPTY_ITERABLE;
  402.     }

  403.     /**
  404.      * Returns an empty iterator if the argument is {@code null},
  405.      * or {@code iterable.iterator()} otherwise.
  406.      *
  407.      * @param <E> the element type
  408.      * @param iterable  the iterable, possibly {@code null}
  409.      * @return an empty iterator if the argument is {@code null}
  410.      */
  411.     private static <E> Iterator<E> emptyIteratorIfNull(final Iterable<E> iterable) {
  412.         return iterable != null ? iterable.iterator() : IteratorUtils.<E>emptyIterator();
  413.     }

  414.     /**
  415.      * Returns a view of the given iterable that only contains elements matching
  416.      * the provided predicate.
  417.      * <p>
  418.      * The returned iterable's iterator supports {@code remove()} when the
  419.      * corresponding input iterator supports it.
  420.      * </p>
  421.      *
  422.      * @param <E> the element type
  423.      * @param iterable  the iterable to filter, may not be null
  424.      * @param predicate  the predicate used to filter elements, may not be null
  425.      * @return a filtered view on the specified iterable
  426.      * @throws NullPointerException if either iterable or predicate is null
  427.      */
  428.     public static <E> Iterable<E> filteredIterable(final Iterable<E> iterable,
  429.                                                    final Predicate<? super E> predicate) {
  430.         Objects.requireNonNull(iterable, "iterable");
  431.         Objects.requireNonNull(predicate, "predicate");
  432.         return new FluentIterable<E>() {
  433.             @Override
  434.             public Iterator<E> iterator() {
  435.                 return IteratorUtils.filteredIterator(emptyIteratorIfNull(iterable), predicate);
  436.             }
  437.         };
  438.     }

  439.     /**
  440.      * Finds the first element in the given iterable which matches the given predicate.
  441.      * <p>
  442.      * A {@code null} or empty iterator returns null.
  443.      * </p>
  444.      *
  445.      * @param <E> the element type
  446.      * @param iterable  the iterable to search, may be null
  447.      * @param predicate  the predicate to use, must not be null
  448.      * @return the first element of the iterable which matches the predicate or null if none could be found
  449.      * @throws NullPointerException if predicate is null
  450.      */
  451.     public static <E> E find(final Iterable<E> iterable, final Predicate<? super E> predicate) {
  452.         return IteratorUtils.find(emptyIteratorIfNull(iterable), predicate);
  453.     }

  454.     /**
  455.      * Shortcut for {@code get(iterator, 0)}.
  456.      * <p>
  457.      * Returns the {@code first} value in the {@code iterable}'s {@link Iterator}, throwing
  458.      * {@code IndexOutOfBoundsException} if there is no such element.
  459.      * </p>
  460.      * <p>
  461.      * If the {@link Iterable} is a {@link List}, then it will use {@link List#get(int)}.
  462.      * </p>
  463.      *
  464.      * @param <T> the type of object in the {@link Iterable}.
  465.      * @param iterable  the {@link Iterable} to get a value from, may be null
  466.      * @return the first object
  467.      * @throws IndexOutOfBoundsException if the request is invalid
  468.      * @since 4.2
  469.      */
  470.     public static <T> T first(final Iterable<T> iterable) {
  471.         return get(iterable, 0);
  472.     }

  473.     /**
  474.      * Applies the closure to each element of the provided iterable.
  475.      *
  476.      * @param <E> the element type
  477.      * @param iterable  the iterator to use, may be null
  478.      * @param closure  the closure to apply to each element, may not be null
  479.      * @throws NullPointerException if closure is null
  480.      */
  481.     public static <E> void forEach(final Iterable<E> iterable, final Closure<? super E> closure) {
  482.         IteratorUtils.forEach(emptyIteratorIfNull(iterable), closure);
  483.     }

  484.     /**
  485.      * Executes the given closure on each but the last element in the iterable.
  486.      * <p>
  487.      * If the input iterable is null no change is made.
  488.      * </p>
  489.      *
  490.      * @param <E> the type of object the {@link Iterable} contains
  491.      * @param iterable  the iterable to get the input from, may be null
  492.      * @param closure  the closure to perform, may not be null
  493.      * @return the last element in the iterable, or null if iterable is null or empty
  494.      */
  495.     public static <E> E forEachButLast(final Iterable<E> iterable, final Closure<? super E> closure) {
  496.         return IteratorUtils.forEachButLast(emptyIteratorIfNull(iterable), closure);
  497.     }

  498.     /**
  499.      * Returns the number of occurrences of the provided object in the iterable.
  500.      *
  501.      * @param <E> the element type that the {@link Iterable} may contain
  502.      * @param <T> the element type of the object to find
  503.      * @param iterable  the {@link Iterable} to search
  504.      * @param obj  the object to find the cardinality of
  505.      * @return the number of occurrences of obj in iterable
  506.      */
  507.     public static <E, T extends E> int frequency(final Iterable<E> iterable, final T obj) {
  508.         if (iterable instanceof Set<?>) {
  509.             return ((Set<E>) iterable).contains(obj) ? 1 : 0;
  510.         }
  511.         if (iterable instanceof Bag<?>) {
  512.             return ((Bag<E>) iterable).getCount(obj);
  513.         }
  514.         return size(filteredIterable(emptyIfNull(iterable), EqualPredicate.<E>equalPredicate(obj)));
  515.     }

  516.     /**
  517.      * Gets the {@code index}-th value in the {@code iterable}'s {@link Iterator}, throwing
  518.      * {@code IndexOutOfBoundsException} if there is no such element.
  519.      * <p>
  520.      * If the {@link Iterable} is a {@link List}, then it will use {@link List#get(int)}.
  521.      * </p>
  522.      *
  523.      * @param <T> the type of object in the {@link Iterable}.
  524.      * @param iterable  the {@link Iterable} to get a value from, may be null
  525.      * @param index  the index to get
  526.      * @return the object at the specified index
  527.      * @throws IndexOutOfBoundsException if the index is invalid
  528.      */
  529.     public static <T> T get(final Iterable<T> iterable, final int index) {
  530.         CollectionUtils.checkIndexBounds(index);
  531.         if (iterable instanceof List<?>) {
  532.             return ((List<T>) iterable).get(index);
  533.         }
  534.         return IteratorUtils.get(emptyIteratorIfNull(iterable), index);
  535.     }

  536.     /**
  537.      * Returns the index of the first element in the specified iterable that
  538.      * matches the given predicate.
  539.      * <p>
  540.      * A {@code null} or empty iterable returns -1.
  541.      * </p>
  542.      *
  543.      * @param <E> the element type
  544.      * @param iterable  the iterable to search, may be null
  545.      * @param predicate  the predicate to use, must not be null
  546.      * @return the index of the first element which matches the predicate or -1 if none matches
  547.      * @throws NullPointerException if predicate is null
  548.      */
  549.     public static <E> int indexOf(final Iterable<E> iterable, final Predicate<? super E> predicate) {
  550.         return IteratorUtils.indexOf(emptyIteratorIfNull(iterable), predicate);
  551.     }

  552.     /**
  553.      * Answers true if the provided iterable is empty.
  554.      * <p>
  555.      * A {@code null} iterable returns true.
  556.      * </p>
  557.      *
  558.      * @param iterable  the {@link Iterable to use}, may be null
  559.      * @return true if the iterable is null or empty, false otherwise
  560.      */
  561.     public static boolean isEmpty(final Iterable<?> iterable) {
  562.         if (iterable instanceof Collection<?>) {
  563.             return ((Collection<?>) iterable).isEmpty();
  564.         }
  565.         return IteratorUtils.isEmpty(emptyIteratorIfNull(iterable));
  566.     }

  567.     /**
  568.      * Returns a view of the given iterable which will cycle infinitely over
  569.      * its elements.
  570.      * <p>
  571.      * The returned iterable's iterator supports {@code remove()} if
  572.      * {@code iterable.iterator()} does. After {@code remove()} is called, subsequent
  573.      * cycles omit the removed element, which is no longer in {@code iterable}. The
  574.      * iterator's {@code hasNext()} method returns {@code true} until {@code iterable}
  575.      * is empty.
  576.      * </p>
  577.      *
  578.      * @param <E> the element type
  579.      * @param iterable  the iterable to loop, may not be null
  580.      * @return a view of the iterable, providing an infinite loop over its elements
  581.      * @throws NullPointerException if iterable is null
  582.      */
  583.     public static <E> Iterable<E> loopingIterable(final Iterable<E> iterable) {
  584.         Objects.requireNonNull(iterable, "iterable");
  585.         return new FluentIterable<E>() {
  586.             @Override
  587.             public Iterator<E> iterator() {
  588.                 return new LazyIteratorChain<E>() {
  589.                     @Override
  590.                     protected Iterator<? extends E> nextIterator(final int count) {
  591.                         if (IterableUtils.isEmpty(iterable)) {
  592.                             return null;
  593.                         }
  594.                         return iterable.iterator();
  595.                     }
  596.                 };
  597.             }
  598.         };
  599.     }

  600.     /**
  601.      * Answers true if a predicate is true for every element of an iterable.
  602.      * <p>
  603.      * A {@code null} or empty iterable returns true.
  604.      * </p>
  605.      *
  606.      * @param <E> the type of object the {@link Iterable} contains
  607.      * @param iterable  the {@link Iterable} to use, may be null
  608.      * @param predicate  the predicate to use, may not be null
  609.      * @return true if every element of the collection matches the predicate or if the
  610.      *   collection is empty, false otherwise
  611.      * @throws NullPointerException if predicate is null
  612.      */
  613.     public static <E> boolean matchesAll(final Iterable<E> iterable, final Predicate<? super E> predicate) {
  614.         return IteratorUtils.matchesAll(emptyIteratorIfNull(iterable), predicate);
  615.     }

  616.     /**
  617.      * Answers true if a predicate is true for any element of the iterable.
  618.      * <p>
  619.      * A {@code null} or empty iterable returns false.
  620.      * </p>
  621.      *
  622.      * @param <E> the type of object the {@link Iterable} contains
  623.      * @param iterable  the {@link Iterable} to use, may be null
  624.      * @param predicate  the predicate to use, may not be null
  625.      * @return true if any element of the collection matches the predicate, false otherwise
  626.      * @throws NullPointerException if predicate is null
  627.      */
  628.     public static <E> boolean matchesAny(final Iterable<E> iterable, final Predicate<? super E> predicate) {
  629.         return IteratorUtils.matchesAny(emptyIteratorIfNull(iterable), predicate);
  630.     }

  631.     /**
  632.      * Partitions all elements from iterable into separate output collections,
  633.      * based on the evaluation of the given predicates.
  634.      * <p>
  635.      * For each predicate, the returned list will contain a collection holding
  636.      * all elements of the input iterable matching the predicate. The last collection
  637.      * contained in the list will hold all elements which didn't match any predicate:
  638.      * </p>
  639.      * <pre>
  640.      *  [C1, C2, R] = partition(I, P1, P2) with
  641.      *  I = input
  642.      *  P1 = first predicate
  643.      *  P2 = second predicate
  644.      *  C1 = collection of elements matching P1
  645.      *  C2 = collection of elements matching P2
  646.      *  R = collection of elements rejected by all predicates
  647.      * </pre>
  648.      * <p>
  649.      * <strong>Note</strong>: elements are only added to the output collection of the first matching
  650.      * predicate, determined by the order of arguments.
  651.      * </p>
  652.      * <p>
  653.      * If the input iterable is {@code null}, the same is returned as for an
  654.      * empty iterable.
  655.      * If no predicates have been provided, all elements of the input collection
  656.      * will be added to the rejected collection.
  657.      * </p>
  658.      * <p>
  659.      * Example: for an input list [1, 2, 3, 4, 5] calling partition with predicates [x &lt; 3]
  660.      * and [x &lt; 5] will result in the following output: [[1, 2], [3, 4], [5]].
  661.      * </p>
  662.      *
  663.      * @param <O>  the type of object the {@link Iterable} contains
  664.      * @param <R>  the type of the output {@link Collection}
  665.      * @param iterable  the collection to get the input from, may be null
  666.      * @param partitionFactory  the factory used to create the output collections
  667.      * @param predicates  the predicates to use, may not be null
  668.      * @return a list containing the output collections
  669.      * @throws NullPointerException if any predicate is null
  670.      */
  671.     public static <O, R extends Collection<O>> List<R> partition(final Iterable<? extends O> iterable,
  672.             final Factory<R> partitionFactory, final Predicate<? super O>... predicates) {

  673.         if (iterable == null) {
  674.             final Iterable<O> empty = emptyIterable();
  675.             return partition(empty, partitionFactory, predicates);
  676.         }

  677.         Objects.requireNonNull(predicates, "predicates");

  678.         for (final Predicate<?> predicate : predicates) {
  679.             Objects.requireNonNull(predicate, "predicate");
  680.         }

  681.         if (predicates.length < 1) {
  682.             // return the entire input collection as a single partition
  683.             final R singlePartition = partitionFactory.get();
  684.             CollectionUtils.addAll(singlePartition, iterable);
  685.             return Collections.singletonList(singlePartition);
  686.         }

  687.         // create the empty partitions
  688.         final int numberOfPredicates = predicates.length;
  689.         final int numberOfPartitions = numberOfPredicates + 1;
  690.         final List<R> partitions = new ArrayList<>(numberOfPartitions);
  691.         for (int i = 0; i < numberOfPartitions; ++i) {
  692.             partitions.add(partitionFactory.get());
  693.         }

  694.         // for each element in inputCollection:
  695.         // find the first predicate that evaluates to true.
  696.         // if there is a predicate, add the element to the corresponding partition.
  697.         // if there is no predicate, add it to the last, catch-all partition.
  698.         for (final O element : iterable) {
  699.             boolean elementAssigned = false;
  700.             for (int i = 0; i < numberOfPredicates; ++i) {
  701.                 if (predicates[i].test(element)) {
  702.                     partitions.get(i).add(element);
  703.                     elementAssigned = true;
  704.                     break;
  705.                 }
  706.             }

  707.             if (!elementAssigned) {
  708.                 // no predicates evaluated to true
  709.                 // add element to last partition
  710.                 partitions.get(numberOfPredicates).add(element);
  711.             }
  712.         }

  713.         return partitions;
  714.     }

  715.     /**
  716.      * Partitions all elements from iterable into separate output collections,
  717.      * based on the evaluation of the given predicate.
  718.      * <p>
  719.      * For each predicate, the result will contain a list holding all elements of the
  720.      * input iterable matching the predicate. The last list will hold all elements
  721.      * which didn't match any predicate:
  722.      * </p>
  723.      * <pre>
  724.      *  [C1, R] = partition(I, P1) with
  725.      *  I = input
  726.      *  P1 = first predicate
  727.      *  C1 = collection of elements matching P1
  728.      *  R = collection of elements rejected by all predicates
  729.      * </pre>
  730.      * <p>
  731.      * If the input iterable is {@code null}, the same is returned as for an
  732.      * empty iterable.
  733.      * </p>
  734.      * <p>
  735.      * Example: for an input list [1, 2, 3, 4, 5] calling partition with a predicate [x &lt; 3]
  736.      * will result in the following output: [[1, 2], [3, 4, 5]].
  737.      * </p>
  738.      *
  739.      * @param <O>  the type of object the {@link Iterable} contains
  740.      * @param iterable  the iterable to partition, may be null
  741.      * @param predicate  the predicate to use, may not be null
  742.      * @return a list containing the output collections
  743.      * @throws NullPointerException if predicate is null
  744.      */
  745.     public static <O> List<List<O>> partition(final Iterable<? extends O> iterable,
  746.                                               final Predicate<? super O> predicate) {
  747.         Objects.requireNonNull(predicate, "predicate");
  748.         @SuppressWarnings({ "unchecked", "rawtypes" }) // safe
  749.         final Factory<List<O>> factory = FactoryUtils.instantiateFactory((Class) ArrayList.class);
  750.         @SuppressWarnings("unchecked") // safe
  751.         final Predicate<? super O>[] predicates = new Predicate[] { predicate };
  752.         return partition(iterable, factory, predicates);
  753.     }

  754.     /**
  755.      * Partitions all elements from iterable into separate output collections,
  756.      * based on the evaluation of the given predicates.
  757.      * <p>
  758.      * For each predicate, the result will contain a list holding all elements of the
  759.      * input iterable matching the predicate. The last list will hold all elements
  760.      * which didn't match any predicate:
  761.      * </p>
  762.      * <pre>
  763.      *  [C1, C2, R] = partition(I, P1, P2) with
  764.      *  I = input
  765.      *  P1 = first predicate
  766.      *  P2 = second predicate
  767.      *  C1 = collection of elements matching P1
  768.      *  C2 = collection of elements matching P2
  769.      *  R = collection of elements rejected by all predicates
  770.      * </pre>
  771.      * <p>
  772.      * <strong>Note</strong>: elements are only added to the output collection of the first matching
  773.      * predicate, determined by the order of arguments.
  774.      * </p>
  775.      * <p>
  776.      * If the input iterable is {@code null}, the same is returned as for an
  777.      * empty iterable.
  778.      * </p>
  779.      * <p>
  780.      * Example: for an input list [1, 2, 3, 4, 5] calling partition with predicates [x &lt; 3]
  781.      * and [x &lt; 5] will result in the following output: [[1, 2], [3, 4], [5]].
  782.      * </p>
  783.      *
  784.      * @param <O>  the type of object the {@link Iterable} contains
  785.      * @param iterable  the collection to get the input from, may be null
  786.      * @param predicates  the predicates to use, may not be null
  787.      * @return a list containing the output collections
  788.      * @throws NullPointerException if any predicate is null
  789.      */
  790.     public static <O> List<List<O>> partition(final Iterable<? extends O> iterable,
  791.                                               final Predicate<? super O>... predicates) {

  792.         @SuppressWarnings({ "unchecked", "rawtypes" }) // safe
  793.         final Factory<List<O>> factory = FactoryUtils.instantiateFactory((Class) ArrayList.class);
  794.         return partition(iterable, factory, predicates);
  795.     }

  796.     /**
  797.      * Returns a reversed view of the given iterable.
  798.      * <p>
  799.      * In case the provided iterable is a {@link List} instance, a
  800.      * {@link ReverseListIterator} will be used to reverse the traversal
  801.      * order, otherwise an intermediate {@link List} needs to be created.
  802.      * </p>
  803.      * <p>
  804.      * The returned iterable's iterator supports {@code remove()} if the
  805.      * provided iterable is a {@link List} instance.
  806.      * </p>
  807.      *
  808.      * @param <E> the element type
  809.      * @param iterable  the iterable to use, may not be null
  810.      * @return a reversed view of the specified iterable
  811.      * @throws NullPointerException if iterable is null
  812.      * @see ReverseListIterator
  813.      */
  814.     public static <E> Iterable<E> reversedIterable(final Iterable<E> iterable) {
  815.         Objects.requireNonNull(iterable, "iterable");
  816.         return new FluentIterable<E>() {
  817.             @Override
  818.             public Iterator<E> iterator() {
  819.                 final List<E> list = iterable instanceof List<?> ?
  820.                         (List<E>) iterable :
  821.                         IteratorUtils.toList(iterable.iterator());
  822.                 return new ReverseListIterator<>(list);
  823.             }
  824.         };
  825.     }

  826.     /**
  827.      * Returns the number of elements contained in the given iterator.
  828.      * <p>
  829.      * A {@code null} or empty iterator returns {@code 0}.
  830.      * </p>
  831.      *
  832.      * @param iterable  the iterable to check, may be null
  833.      * @return the number of elements contained in the iterable
  834.      */
  835.     public static int size(final Iterable<?> iterable) {
  836.         if (iterable == null) {
  837.             return 0;
  838.         }
  839.         if (iterable instanceof Collection<?>) {
  840.             return ((Collection<?>) iterable).size();
  841.         }
  842.         return IteratorUtils.size(emptyIteratorIfNull(iterable));
  843.     }

  844.     /**
  845.      * Returns a view of the given iterable that skips the first N elements.
  846.      * <p>
  847.      * The returned iterable's iterator supports {@code remove()} when the corresponding
  848.      * input iterator supports it.
  849.      * </p>
  850.      *
  851.      * @param <E> the element type
  852.      * @param iterable  the iterable to use, may not be null
  853.      * @param elementsToSkip  the number of elements to skip from the start, must not be negative
  854.      * @return a view of the specified iterable, skipping the first N elements
  855.      * @throws IllegalArgumentException if elementsToSkip is negative
  856.      * @throws NullPointerException if iterable is null
  857.      */
  858.     public static <E> Iterable<E> skippingIterable(final Iterable<E> iterable, final long elementsToSkip) {
  859.         Objects.requireNonNull(iterable, "iterable");
  860.         if (elementsToSkip < 0) {
  861.             throw new IllegalArgumentException("ElementsToSkip parameter must not be negative.");
  862.         }

  863.         return new FluentIterable<E>() {
  864.             @Override
  865.             public Iterator<E> iterator() {
  866.                 return IteratorUtils.skippingIterator(iterable.iterator(), elementsToSkip);
  867.             }
  868.         };
  869.     }

  870.     /**
  871.      * Gets a new list with the contents of the provided iterable.
  872.      *
  873.      * @param <E> the element type
  874.      * @param iterable  the iterable to use, may be null
  875.      * @return a list of the iterator contents
  876.      */
  877.     public static <E> List<E> toList(final Iterable<E> iterable) {
  878.         return IteratorUtils.toList(emptyIteratorIfNull(iterable));
  879.     }

  880.     /**
  881.      * Returns a string representation of the elements of the specified iterable.
  882.      * <p>
  883.      * The string representation consists of a list of the iterable's elements,
  884.      * enclosed in square brackets ({@code "[]"}). Adjacent elements are separated
  885.      * by the characters {@code ", "} (a comma followed by a space). Elements are
  886.      * converted to strings as by {@code String.valueOf(Object)}.
  887.      * </p>
  888.      *
  889.      * @param <E> the element type
  890.      * @param iterable  the iterable to convert to a string, may be null
  891.      * @return a string representation of {@code iterable}
  892.      */
  893.     public static <E> String toString(final Iterable<E> iterable) {
  894.         return IteratorUtils.toString(emptyIteratorIfNull(iterable));
  895.     }

  896.     /**
  897.      * Returns a string representation of the elements of the specified iterable.
  898.      * <p>
  899.      * The string representation consists of a list of the iterable's elements,
  900.      * enclosed in square brackets ({@code "[]"}). Adjacent elements are separated
  901.      * by the characters {@code ", "} (a comma followed by a space). Elements are
  902.      * converted to strings as by using the provided {@code transformer}.
  903.      * </p>
  904.      *
  905.      * @param <E> the element type
  906.      * @param iterable  the iterable to convert to a string, may be null
  907.      * @param transformer  the transformer used to get a string representation of an element
  908.      * @return a string representation of {@code iterable}
  909.      * @throws NullPointerException if {@code transformer} is null
  910.      */
  911.     public static <E> String toString(final Iterable<E> iterable,
  912.                                       final Transformer<? super E, String> transformer) {
  913.         Objects.requireNonNull(transformer, "transformer");
  914.         return IteratorUtils.toString(emptyIteratorIfNull(iterable), transformer);
  915.     }

  916.     /**
  917.      * Returns a string representation of the elements of the specified iterable.
  918.      * <p>
  919.      * The string representation consists of a list of the iterable's elements,
  920.      * enclosed by the provided {@code prefix} and {@code suffix}. Adjacent elements
  921.      * are separated by the provided {@code delimiter}. Elements are converted to
  922.      * strings as by using the provided {@code transformer}.
  923.      * </p>
  924.      *
  925.      * @param <E> the element type
  926.      * @param iterable  the iterable to convert to a string, may be null
  927.      * @param transformer  the transformer used to get a string representation of an element
  928.      * @param delimiter  the string to delimit elements
  929.      * @param prefix  the prefix, prepended to the string representation
  930.      * @param suffix  the suffix, appended to the string representation
  931.      * @return a string representation of {@code iterable}
  932.      * @throws NullPointerException if either transformer, delimiter, prefix or suffix is null
  933.      */
  934.     public static <E> String toString(final Iterable<E> iterable,
  935.                                       final Transformer<? super E, String> transformer,
  936.                                       final String delimiter,
  937.                                       final String prefix,
  938.                                       final String suffix) {
  939.         return IteratorUtils.toString(emptyIteratorIfNull(iterable),
  940.                                       transformer, delimiter, prefix, suffix);
  941.     }

  942.     /**
  943.      * Returns a transformed view of the given iterable where all of its elements
  944.      * have been transformed by the provided transformer.
  945.      * <p>
  946.      * The returned iterable's iterator supports {@code remove()} when the corresponding
  947.      * input iterator supports it.
  948.      * </p>
  949.      *
  950.      * @param <I>  the input element type
  951.      * @param <O>  the output element type
  952.      * @param iterable  the iterable to transform, may not be null
  953.      * @param transformer  the transformer, must not be null
  954.      * @return a transformed view of the specified iterable
  955.      * @throws NullPointerException if either iterable or transformer is null
  956.      */
  957.     public static <I, O> Iterable<O> transformedIterable(final Iterable<I> iterable,
  958.                                                          final Transformer<? super I, ? extends O> transformer) {
  959.         Objects.requireNonNull(iterable, "iterable");
  960.         Objects.requireNonNull(transformer, "transformer");
  961.         return new FluentIterable<O>() {
  962.             @Override
  963.             public Iterator<O> iterator() {
  964.                 return IteratorUtils.transformedIterator(iterable.iterator(), transformer);
  965.             }
  966.         };
  967.     }

  968.     /**
  969.      * Returns a unique view of the given iterable.
  970.      * <p>
  971.      * The returned iterable's iterator supports {@code remove()} when the
  972.      * corresponding input iterator supports it. Calling {@code remove()}
  973.      * will only remove a single element from the underlying iterator.
  974.      * </p>
  975.      *
  976.      * @param <E> the element type
  977.      * @param iterable  the iterable to use, may not be null
  978.      * @return a unique view of the specified iterable
  979.      * @throws NullPointerException if iterable is null
  980.      */
  981.     public static <E> Iterable<E> uniqueIterable(final Iterable<E> iterable) {
  982.         Objects.requireNonNull(iterable, "iterable");
  983.         return new FluentIterable<E>() {
  984.             @Override
  985.             public Iterator<E> iterator() {
  986.                 return new UniqueFilterIterator<>(iterable.iterator());
  987.             }
  988.         };
  989.     }

  990.     /**
  991.      * Returns an unmodifiable view of the given iterable.
  992.      * <p>
  993.      * The returned iterable's iterator does not support {@code remove()}.
  994.      * </p>
  995.      *
  996.      * @param <E> the element type
  997.      * @param iterable  the iterable to use, may not be null
  998.      * @return an unmodifiable view of the specified iterable
  999.      * @throws NullPointerException if iterable is null
  1000.      */
  1001.     public static <E> Iterable<E> unmodifiableIterable(final Iterable<E> iterable) {
  1002.         Objects.requireNonNull(iterable, "iterable");
  1003.         if (iterable instanceof UnmodifiableIterable<?>) {
  1004.             return iterable;
  1005.         }
  1006.         return new UnmodifiableIterable<>(iterable);
  1007.     }

  1008.     /**
  1009.      * Interleaves two iterables into a single iterable.
  1010.      * <p>
  1011.      * The returned iterable has an iterator that traverses the elements in {@code a}
  1012.      * and {@code b} in alternating order. The source iterators are not polled until
  1013.      * necessary.
  1014.      * </p>
  1015.      * <p>
  1016.      * The returned iterable's iterator supports {@code remove()} when the corresponding
  1017.      * input iterator supports it.
  1018.      * </p>
  1019.      *
  1020.      * @param <E> the element type
  1021.      * @param a  the first iterable, may not be null
  1022.      * @param b  the second iterable, may not be null
  1023.      * @return a new iterable, interleaving the provided iterables
  1024.      * @throws NullPointerException if either a or b is null
  1025.      */
  1026.     public static <E> Iterable<E> zippingIterable(final Iterable<? extends E> a,
  1027.                                                   final Iterable<? extends E> b) {
  1028.         Objects.requireNonNull(a, "iterable");
  1029.         Objects.requireNonNull(b, "iterable");
  1030.         return new FluentIterable<E>() {
  1031.             @Override
  1032.             public Iterator<E> iterator() {
  1033.                 return IteratorUtils.zippingIterator(a.iterator(), b.iterator());
  1034.             }
  1035.         };
  1036.     }

  1037.     /**
  1038.      * Interleaves two iterables into a single iterable.
  1039.      * <p>
  1040.      * The returned iterable has an iterator that traverses the elements in {@code a} and {@code b} in alternating order. The source iterators are not polled
  1041.      * until necessary.
  1042.      * </p>
  1043.      * <p>
  1044.      * The returned iterable's iterator supports {@code remove()} when the corresponding input iterator supports it.
  1045.      * </p>
  1046.      *
  1047.      * @param <E>    the element type
  1048.      * @param first  the first iterable, may not be null
  1049.      * @param others the array of iterables to interleave, may not be null
  1050.      * @return a new iterable, interleaving the provided iterables
  1051.      * @throws NullPointerException if either of the provided iterables is null
  1052.      */
  1053.     public static <E> Iterable<E> zippingIterable(final Iterable<? extends E> first, final Iterable<? extends E>... others) {
  1054.         Objects.requireNonNull(first, "iterable");
  1055.         checkNotNull(others);
  1056.         return new FluentIterable<E>() {
  1057.             @Override
  1058.             public Iterator<E> iterator() {
  1059.                 @SuppressWarnings("unchecked") // safe
  1060.                 final Iterator<? extends E>[] iterators = new Iterator[others.length + 1];
  1061.                 iterators[0] = first.iterator();
  1062.                 for (int i = 0; i < others.length; i++) {
  1063.                     iterators[i + 1] = others[i].iterator();
  1064.                 }
  1065.                 return IteratorUtils.zippingIterator(iterators);
  1066.             }
  1067.         };
  1068.     }

  1069.     /**
  1070.      * Make private in 5.0.
  1071.      *
  1072.      * @deprecated TODO Make private in 5.0.
  1073.      */
  1074.     @Deprecated
  1075.     public IterableUtils() {
  1076.         // empty
  1077.     }
  1078. }