    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      https://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017
    018package org.apache.commons.collections4;
    019
    020import java.util.ArrayList;
    021import java.util.Collection;
    022import java.util.Collections;
    023import java.util.Comparator;
    024import java.util.HashSet;
    025import java.util.Iterator;
    026import java.util.LinkedHashSet;
    027import java.util.List;
    028import java.util.Objects;
    029import java.util.Set;
    030import java.util.function.ToIntFunction;
    031
    032import org.apache.commons.collections4.functors.EqualPredicate;
    033import org.apache.commons.collections4.functors.NullPredicate;
    034import org.apache.commons.collections4.iterators.LazyIteratorChain;
    035import org.apache.commons.collections4.iterators.ReverseListIterator;
    036import org.apache.commons.collections4.iterators.UniqueFilterIterator;
    037
    038/**
    039 * Provides utility methods and decorators for {@link Iterable} instances.
    040 * <p>
    041 * <strong>Note</strong>: This utility class has been designed with fail-fast argument checking.
    042 * </p>
    043 * <ul>
    044 * <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
    045 * null Iterable is passed as argument.</li>
    046 * <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.
    047 * For other arguments which are null, a {@link Predicate} will result in a {@link NullPointerException}. Exception: passing a null {@link Comparator} is
    048 * equivalent to a Comparator with natural ordering.</li>
    049 * </ul>
    050 *
    051 * @since 4.1
    052 */
    053public class IterableUtils {
    054
    055    /**
    056     * Inner class to distinguish unmodifiable instances.
    057     */
    058    private static final class UnmodifiableIterable<E> extends FluentIterable<E> {
    059
    060        private final Iterable<E> iterable;
    061
    062        UnmodifiableIterable(final Iterable<E> iterable) {
    063            this.iterable = iterable;
    064        }
    065
    066        @Override
    067        public Iterator<E> iterator() {
    068            return IteratorUtils.unmodifiableIterator(iterable.iterator());
    069        }
    070    }
    071
    072    /**
    073     * An empty iterable.
    074     */
    075    @SuppressWarnings("rawtypes")
    076    static final FluentIterable EMPTY_ITERABLE = new FluentIterable<Object>() {
    077
    078        @Override
    079        public Iterator<Object> iterator() {
    080            return IteratorUtils.emptyIterator();
    081        }
    082    };
    083
    084    /**
    085     * Returns a view of the given iterable that contains at most the given number of elements.
    086     * <p>
    087     * The returned iterable's iterator supports {@code remove()} when the corresponding input iterator supports it.
    088     * </p>
    089     *
    090     * @param <E>      The element type.
    091     * @param iterable The iterable to limit, may not be null.
    092     * @param maxSize  The maximum number of elements, must not be negative.
    093     * @return A bounded view on the specified iterable.
    094     * @throws IllegalArgumentException if maxSize is negative.
    095     * @throws NullPointerException     if iterable is null.
    096     */
    097    public static <E> Iterable<E> boundedIterable(final Iterable<E> iterable, final long maxSize) {
    098        Objects.requireNonNull(iterable, "iterable");
    099        if (maxSize < 0) {
    100            throw new IllegalArgumentException("MaxSize parameter must not be negative.");
    101        }
    102        return new FluentIterable<E>() {
    103
    104            @Override
    105            public Iterator<E> iterator() {
    106                return IteratorUtils.boundedIterator(iterable.iterator(), maxSize);
    107            }
    108        };
    109    }
    110
    111    /**
    112     * Combines the provided iterables into a single iterable.
    113     * <p>
    114     * The returned iterable has an iterator that traverses the elements in the order of the arguments, i.e. iterables[0], iterables[1], .... The source
    115     * iterators are not polled until necessary.
    116     * </p>
    117     * <p>
    118     * The returned iterable's iterator supports {@code remove()} when the corresponding input iterator supports it.
    119     * </p>
    120     *
    121     * @param <E>       The element type.
    122     * @param iterables The iterables to combine, may not be null.
    123     * @return A new iterable, combining the provided iterables.
    124     * @throws NullPointerException if either of the provided iterables is null.
    125     */
    126    public static <E> Iterable<E> chainedIterable(final Iterable<? extends E>... iterables) {
    127        checkNotNull(iterables);
    128        return new FluentIterable<E>() {
    129
    130            @Override
    131            public Iterator<E> iterator() {
    132                return new LazyIteratorChain<E>() {
    133
    134                    @Override
    135                    protected Iterator<? extends E> nextIterator(final int count) {
    136                        if (count > iterables.length) {
    137                            return null;
    138                        }
    139                        return iterables[count - 1].iterator();
    140                    }
    141                };
    142            }
    143        };
    144    }
    145
    146    /**
    147     * Combines two iterables into a single iterable.
    148     * <p>
    149     * The returned iterable has an iterator that traverses the elements in {@code a}, followed by the elements in {@code b}. The source iterators are not
    150     * polled until necessary.
    151     * </p>
    152     * <p>
    153     * The returned iterable's iterator supports {@code remove()} when the corresponding input iterator supports it.
    154     * </p>
    155     *
    156     * @param <E> The element type.
    157     * @param a   The first iterable, may not be null.
    158     * @param b   The second iterable, may not be null.
    159     * @return A new iterable, combining the provided iterables.
    160     * @throws NullPointerException if either a or b is null.
    161     */
    162    @SuppressWarnings("unchecked")
    163    public static <E> Iterable<E> chainedIterable(final Iterable<? extends E> a, final Iterable<? extends E> b) {
    164        return chainedIterable(new Iterable[] { a, b });
    165    }
    166
    167    /**
    168     * Combines three iterables into a single iterable.
    169     * <p>
    170     * The returned iterable has an iterator that traverses the elements in {@code a}, followed by the elements in {@code b} and {@code c}. The source iterators
    171     * are not polled until necessary.
    172     * </p>
    173     * <p>
    174     * The returned iterable's iterator supports {@code remove()} when the corresponding input iterator supports it.
    175     * </p>
    176     *
    177     * @param <E> The element type.
    178     * @param a   The first iterable, may not be null.
    179     * @param b   The second iterable, may not be null.
    180     * @param c   The third iterable, may not be null.
    181     * @return A new iterable, combining the provided iterables.
    182     * @throws NullPointerException if either of the provided iterables is null.
    183     */
    184    @SuppressWarnings("unchecked")
    185    public static <E> Iterable<E> chainedIterable(final Iterable<? extends E> a, final Iterable<? extends E> b, final Iterable<? extends E> c) {
    186        return chainedIterable(new Iterable[] { a, b, c });
    187    }
    188
    189    /**
    190     * Combines four iterables into a single iterable.
    191     * <p>
    192     * The returned iterable has an iterator that traverses the elements in {@code a}, followed by the elements in {@code b}, {@code c} and {@code d}. The
    193     * source iterators are not polled until necessary.
    194     * </p>
    195     * <p>
    196     * The returned iterable's iterator supports {@code remove()} when the corresponding input iterator supports it.
    197     * </p>
    198     *
    199     * @param <E> The element type.
    200     * @param a   The first iterable, may not be null.
    201     * @param b   The second iterable, may not be null.
    202     * @param c   The third iterable, may not be null.
    203     * @param d   The fourth iterable, may not be null.
    204     * @return A new iterable, combining the provided iterables.
    205     * @throws NullPointerException if either of the provided iterables is null.
    206     */
    207    @SuppressWarnings("unchecked")
    208    public static <E> Iterable<E> chainedIterable(final Iterable<? extends E> a, final Iterable<? extends E> b, final Iterable<? extends E> c,
    209            final Iterable<? extends E> d) {
    210        return chainedIterable(new Iterable[] { a, b, c, d });
    211    }
    212
    213    /**
    214     * Fail-fast check for null arguments.
    215     *
    216     * @param iterables The iterables to check.
    217     * @throws NullPointerException if the argument or any of its contents is null.
    218     */
    219    static void checkNotNull(final Iterable<?>... iterables) {
    220        Objects.requireNonNull(iterables, "iterables");
    221        for (final Iterable<?> iterable : iterables) {
    222            Objects.requireNonNull(iterable, "iterable");
    223        }
    224    }
    225
    226    /**
    227     * Combines the two provided iterables into an ordered iterable using the provided comparator. If the comparator is null, natural ordering will be used.
    228     * <p>
    229     * The returned iterable's iterator supports {@code remove()} when the corresponding input iterator supports it.
    230     * </p>
    231     *
    232     * @param <E>        The element type.
    233     * @param comparator The comparator defining an ordering over the elements, may be null, in which case natural ordering will be used.
    234     * @param a          The first iterable, may not be null.
    235     * @param b          The second iterable, may not be null.
    236     * @return A filtered view on the specified iterable.
    237     * @throws NullPointerException if either of the provided iterables is null.
    238     */
    239    public static <E> Iterable<E> collatedIterable(final Comparator<? super E> comparator, final Iterable<? extends E> a, final Iterable<? extends E> b) {
    240        checkNotNull(a, b);
    241        return new FluentIterable<E>() {
    242
    243            @Override
    244            public Iterator<E> iterator() {
    245                return IteratorUtils.collatedIterator(comparator, a.iterator(), b.iterator());
    246            }
    247        };
    248    }
    249
    250    /**
    251     * Combines the two provided iterables into an ordered iterable using natural ordering.
    252     * <p>
    253     * The returned iterable's iterator supports {@code remove()} when the corresponding input iterator supports it.
    254     * </p>
    255     *
    256     * @param <E> The element type.
    257     * @param a   The first iterable, must not be null.
    258     * @param b   The second iterable, must not be null.
    259     * @return A filtered view on the specified iterable.
    260     * @throws NullPointerException if either of the provided iterables is null.
    261     */
    262    public static <E> Iterable<E> collatedIterable(final Iterable<? extends E> a, final Iterable<? extends E> b) {
    263        checkNotNull(a, b);
    264        return new FluentIterable<E>() {
    265
    266            @Override
    267            public Iterator<E> iterator() {
    268                return IteratorUtils.collatedIterator(null, a.iterator(), b.iterator());
    269            }
    270        };
    271    }
    272
    273    /**
    274     * Checks if the object is contained in the given iterable. Object equality is tested with an {@code equator} unlike {@link #contains(Iterable, Object)}
    275     * which uses {@link Object#equals(Object)}.
    276     * <p>
    277     * A {@code null} or empty iterable returns false. A {@code null} object will not be passed to the equator, instead a {@link NullPredicate NullPredicate}
    278     * will be used.
    279     * </p>
    280     *
    281     * @param <E>      The type of object the {@link Iterable} contains.
    282     * @param iterable The iterable to check, may be null.
    283     * @param object   The object to check.
    284     * @param equator  The equator to use to check, may not be null.
    285     * @return true if the object is contained in the iterable, false otherwise.
    286     * @throws NullPointerException if equator is null.
    287     */
    288    public static <E> boolean contains(final Iterable<? extends E> iterable, final E object, final Equator<? super E> equator) {
    289        Objects.requireNonNull(equator, "equator");
    290        return matchesAny(iterable, EqualPredicate.equalPredicate(object, equator));
    291    }
    292
    293    /**
    294     * Checks if the object is contained in the given iterable.
    295     * <p>
    296     * A {@code null} or empty iterable returns false.
    297     * </p>
    298     *
    299     * @param <E>      The type of object the {@link Iterable} contains.
    300     * @param iterable The iterable to check, may be null.
    301     * @param object   The object to check.
    302     * @return true if the object is contained in the iterable, false otherwise.
    303     */
    304    public static <E> boolean contains(final Iterable<E> iterable, final Object object) {
    305        if (iterable instanceof Collection<?>) {
    306            return ((Collection<E>) iterable).contains(object);
    307        }
    308        return IteratorUtils.contains(emptyIteratorIfNull(iterable), object);
    309    }
    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    /**
    329     * Finds and returns the List of duplicate elements in the given collection.
    330     *
    331     * @param <E>      The type of elements in the collection.
    332     * @param iterable The list to test, must not be null.
    333     * @return The set of duplicate elements, may be empty.
    334     * @throws NullPointerException if iterable is null.
    335     * @since 4.5.0-M3
    336     */
    337    public static <E> List<E> duplicateList(final Iterable<E> iterable) {
    338        return new ArrayList<>(duplicateSequencedSet(iterable));
    339    }
    340
    341    /**
    342     * Finds and returns the sequenced Set of duplicate elements in the given collection.
    343     * <p>
    344     * Once we are on Java 21 and a new major version, the return type should be SequencedSet.
    345     * </p>
    346     *
    347     * @param <E>      The type of elements in the collection.
    348     * @param iterable The list to test, must not be null.
    349     * @return The set of duplicate elements, may be empty.
    350     * @throws NullPointerException if iterable is null.
    351     * @since 4.5.0-M3
    352     */
    353    public static <E> Set<E> duplicateSequencedSet(final Iterable<E> iterable) {
    354        return duplicateSet(iterable, new LinkedHashSet<>());
    355    }
    356
    357    /**
    358     * Finds and returns the set of duplicate elements in the given collection.
    359     *
    360     * @param <E>      The type of elements in the collection.
    361     * @param iterable The list to test, must not be null.
    362     * @return The set of duplicate elements, may be empty.
    363     * @throws NullPointerException if iterable is null.
    364     * @since 4.5.0-M3
    365     */
    366    public static <E> Set<E> duplicateSet(final Iterable<E> iterable) {
    367        return duplicateSet(iterable, new HashSet<>());
    368    }
    369
    370    /**
    371     * Worker method for {@link #duplicateSet(Collection)} and friends.
    372     *
    373     * @param <C>        The type of Collection.
    374     * @param <E>        The type of elements in the Collection.
    375     * @param iterable   The list to test, must not be null.
    376     * @param duplicates The list to test, must not be null.
    377     * @return The set of duplicate elements, may be empty.
    378     */
    379    static <C extends Collection<E>, E> C duplicateSet(final Iterable<E> iterable, final C duplicates) {
    380        final Set<E> set = new HashSet<>();
    381        for (final E e : iterable) {
    382            (set.contains(e) ? duplicates : set).add(e);
    383        }
    384        return duplicates;
    385    }
    386
    387    /**
    388     * Returns an immutable empty iterable if the argument is null, or the argument itself otherwise.
    389     *
    390     * @param <E>      The element type.
    391     * @param iterable The iterable, may be null.
    392     * @return An empty iterable if the argument is null.
    393     */
    394    public static <E> Iterable<E> emptyIfNull(final Iterable<E> iterable) {
    395        return iterable == null ? IterableUtils.<E>emptyIterable() : iterable;
    396    }
    397
    398    /**
    399     * Gets an empty iterable.
    400     * <p>
    401     * This iterable does not contain any elements.
    402     * </p>
    403     *
    404     * @param <E> The element type.
    405     * @return An empty iterable.
    406     */
    407    @SuppressWarnings("unchecked") // OK, empty collection is compatible with any type
    408    public static <E> Iterable<E> emptyIterable() {
    409        return EMPTY_ITERABLE;
    410    }
    411
    412    /**
    413     * Returns an empty iterator if the argument is {@code null}, or {@code iterable.iterator()} otherwise.
    414     *
    415     * @param <E>      The element type.
    416     * @param iterable The iterable, possibly {@code null}.
    417     * @return An empty iterator if the argument is {@code null}.
    418     */
    419    private static <E> Iterator<E> emptyIteratorIfNull(final Iterable<E> iterable) {
    420        return iterable != null ? iterable.iterator() : IteratorUtils.<E>emptyIterator();
    421    }
    422
    423    /**
    424     * Returns a view of the given iterable that only contains elements matching the provided predicate.
    425     * <p>
    426     * The returned iterable's iterator supports {@code remove()} when the corresponding input iterator supports it.
    427     * </p>
    428     *
    429     * @param <E>       The element type.
    430     * @param iterable  The iterable to filter, may not be null.
    431     * @param predicate The predicate used to filter elements, may not be null.
    432     * @return A filtered view on the specified iterable.
    433     * @throws NullPointerException if either iterable or predicate is null.
    434     */
    435    public static <E> Iterable<E> filteredIterable(final Iterable<E> iterable, final Predicate<? super E> predicate) {
    436        Objects.requireNonNull(iterable, "iterable");
    437        Objects.requireNonNull(predicate, "predicate");
    438        return new FluentIterable<E>() {
    439
    440            @Override
    441            public Iterator<E> iterator() {
    442                return IteratorUtils.filteredIterator(emptyIteratorIfNull(iterable), predicate);
    443            }
    444        };
    445    }
    446
    447    /**
    448     * Finds the first element in the given iterable which matches the given predicate.
    449     * <p>
    450     * A {@code null} or empty iterator returns null.
    451     * </p>
    452     *
    453     * @param <E>       The element type.
    454     * @param iterable  The iterable to search, may be null.
    455     * @param predicate The predicate to use, must not be null.
    456     * @return The first element of the iterable which matches the predicate or null if none could be found.
    457     * @throws NullPointerException if predicate is null.
    458     */
    459    public static <E> E find(final Iterable<E> iterable, final Predicate<? super E> predicate) {
    460        return IteratorUtils.find(emptyIteratorIfNull(iterable), predicate);
    461    }
    462
    463    /**
    464     * Shortcut for {@code get(iterator, 0)}.
    465     * <p>
    466     * Returns the {@code first} value in the {@code iterable}'s {@link Iterator}, throwing {@code IndexOutOfBoundsException} if there is no such element.
    467     * </p>
    468     * <p>
    469     * If the {@link Iterable} is a {@link List}, then it will use {@link List#get(int)}.
    470     * </p>
    471     *
    472     * @param <T>      The type of object in the {@link Iterable}.
    473     * @param iterable The {@link Iterable} to get a value from, may be null.
    474     * @return The first object.
    475     * @throws IndexOutOfBoundsException if the request is invalid.
    476     * @since 4.2
    477     */
    478    public static <T> T first(final Iterable<T> iterable) {
    479        return get(iterable, 0);
    480    }
    481
    482    /**
    483     * Applies the closure to each element of the provided iterable.
    484     *
    485     * @param <E>      The element type.
    486     * @param iterable The iterator to use, may be null.
    487     * @param closure  The closure to apply to each element, may not be null.
    488     * @throws NullPointerException if closure is null.
    489     */
    490    public static <E> void forEach(final Iterable<E> iterable, final Closure<? super E> closure) {
    491        IteratorUtils.forEach(emptyIteratorIfNull(iterable), closure);
    492    }
    493
    494    /**
    495     * Executes the given closure on each but the last element in the iterable.
    496     * <p>
    497     * If the input iterable is null no change is made.
    498     * </p>
    499     *
    500     * @param <E>      The type of object the {@link Iterable} contains.
    501     * @param iterable The iterable to get the input from, may be null.
    502     * @param closure  The closure to perform, may not be null.
    503     * @return The last element in the iterable, or null if iterable is null or empty.
    504     */
    505    public static <E> E forEachButLast(final Iterable<E> iterable, final Closure<? super E> closure) {
    506        return IteratorUtils.forEachButLast(emptyIteratorIfNull(iterable), closure);
    507    }
    508
    509    /**
    510     * Returns the number of occurrences of the provided object in the iterable.
    511     *
    512     * @param <E>      The element type that the {@link Iterable} may contain.
    513     * @param <T>      The element type of the object to find.
    514     * @param iterable The {@link Iterable} to search.
    515     * @param obj      The object to find the cardinality of.
    516     * @return The number of occurrences of obj in iterable.
    517     */
    518    @SuppressWarnings("deprecation") // Bag is supported until removed
    519    public static <E, T extends E> int frequency(final Iterable<E> iterable, final T obj) {
    520        if (iterable instanceof Set<?>) {
    521            return ((Set<E>) iterable).contains(obj) ? 1 : 0;
    522        }
    523        if (iterable instanceof MultiSet<?>) {
    524            return ((MultiSet<E>) iterable).getCount(obj);
    525        }
    526        if (iterable instanceof Bag<?>) {
    527            return ((Bag<E>) iterable).getCount(obj);
    528        }
    529        return size(filteredIterable(emptyIfNull(iterable), EqualPredicate.<E>equalPredicate(obj)));
    530    }
    531
    532    /**
    533     * Gets the {@code index}-th value in the {@code iterable}'s {@link Iterator}, throwing {@code IndexOutOfBoundsException} if there is no such element.
    534     * <p>
    535     * If the {@link Iterable} is a {@link List}, then it will use {@link List#get(int)}.
    536     * </p>
    537     *
    538     * @param <T>      The type of object in the {@link Iterable}.
    539     * @param iterable The {@link Iterable} to get a value from, may be null.
    540     * @param index    The index to get.
    541     * @return The object at the specified index.
    542     * @throws IndexOutOfBoundsException if the index is invalid.
    543     */
    544    public static <T> T get(final Iterable<T> iterable, final int index) {
    545        CollectionUtils.checkIndexBounds(index);
    546        if (iterable instanceof List<?>) {
    547            return ((List<T>) iterable).get(index);
    548        }
    549        return IteratorUtils.get(emptyIteratorIfNull(iterable), index);
    550    }
    551
    552    /**
    553     * Returns the index of the first element in the specified iterable that matches the given predicate.
    554     * <p>
    555     * A {@code null} or empty iterable returns -1.
    556     * </p>
    557     *
    558     * @param <E>       The element type.
    559     * @param iterable  The iterable to search, may be null.
    560     * @param predicate The predicate to use, must not be null.
    561     * @return The index of the first element which matches the predicate or -1 if none matches.
    562     * @throws NullPointerException if predicate is null.
    563     */
    564    public static <E> int indexOf(final Iterable<E> iterable, final Predicate<? super E> predicate) {
    565        return IteratorUtils.indexOf(emptyIteratorIfNull(iterable), predicate);
    566    }
    567
    568    /**
    569     * Answers true if the provided iterable is empty.
    570     * <p>
    571     * A {@code null} iterable returns true.
    572     * </p>
    573     *
    574     * @param iterable The {@link Iterable to use}, may be null.
    575     * @return true if the iterable is null or empty, false otherwise.
    576     */
    577    public static boolean isEmpty(final Iterable<?> iterable) {
    578        if (iterable instanceof Collection<?>) {
    579            return ((Collection<?>) iterable).isEmpty();
    580        }
    581        return IteratorUtils.isEmpty(emptyIteratorIfNull(iterable));
    582    }
    583
    584    /**
    585     * Returns a view of the given iterable which will cycle infinitely over its elements.
    586     * <p>
    587     * The returned iterable's iterator supports {@code remove()} if {@code iterable.iterator()} does. After {@code remove()} is called, subsequent cycles omit
    588     * the removed element, which is no longer in {@code iterable}. The iterator's {@code hasNext()} method returns {@code true} until {@code iterable} is
    589     * empty.
    590     * </p>
    591     *
    592     * @param <E>      The element type.
    593     * @param iterable The iterable to loop, may not be null.
    594     * @return A view of the iterable, providing an infinite loop over its elements.
    595     * @throws NullPointerException if iterable is null.
    596     */
    597    public static <E> Iterable<E> loopingIterable(final Iterable<E> iterable) {
    598        Objects.requireNonNull(iterable, "iterable");
    599        return new FluentIterable<E>() {
    600
    601            @Override
    602            public Iterator<E> iterator() {
    603                return new LazyIteratorChain<E>() {
    604
    605                    @Override
    606                    protected Iterator<? extends E> nextIterator(final int count) {
    607                        if (IterableUtils.isEmpty(iterable)) { // NOPMD: qualifier is needed here
    608                            return null;
    609                        }
    610                        return iterable.iterator();
    611                    }
    612                };
    613            }
    614        };
    615    }
    616
    617    /**
    618     * Answers true if a predicate is true for every element of an iterable.
    619     * <p>
    620     * A {@code null} or empty iterable returns true.
    621     * </p>
    622     *
    623     * @param <E>       The type of object the {@link Iterable} contains.
    624     * @param iterable  The {@link Iterable} to use, may be null.
    625     * @param predicate The predicate to use, may not be null.
    626     * @return true if every element of the collection matches the predicate or if the collection is empty, false otherwise.
    627     * @throws NullPointerException if predicate is null.
    628     */
    629    public static <E> boolean matchesAll(final Iterable<E> iterable, final Predicate<? super E> predicate) {
    630        return IteratorUtils.matchesAll(emptyIteratorIfNull(iterable), predicate);
    631    }
    632
    633    /**
    634     * Answers true if a predicate is true for any element of the iterable.
    635     * <p>
    636     * A {@code null} or empty iterable returns false.
    637     * </p>
    638     *
    639     * @param <E>       The type of object the {@link Iterable} contains.
    640     * @param iterable  The {@link Iterable} to use, may be null.
    641     * @param predicate The predicate to use, may not be null.
    642     * @return true if any element of the collection matches the predicate, false otherwise.
    643     * @throws NullPointerException if predicate is null.
    644     */
    645    public static <E> boolean matchesAny(final Iterable<E> iterable, final Predicate<? super E> predicate) {
    646        return IteratorUtils.matchesAny(emptyIteratorIfNull(iterable), predicate);
    647    }
    648
    649    /**
    650     * Partitions all elements from iterable into separate output collections, based on the evaluation of the given predicates.
    651     * <p>
    652     * For each predicate, the returned list will contain a collection holding all elements of the input iterable matching the predicate. The last collection
    653     * contained in the list will hold all elements which didn't match any predicate:
    654     * </p>
    655     *
    656     * <pre>
    657     *  [C1, C2, R] = partition(I, P1, P2) with
    658     *  I = input
    659     *  P1 = first predicate
    660     *  P2 = second predicate
    661     *  C1 = collection of elements matching P1
    662     *  C2 = collection of elements matching P2
    663     *  R = collection of elements rejected by all predicates
    664     * </pre>
    665     * <p>
    666     * <strong>Note</strong>: elements are only added to the output collection of the first matching predicate, determined by the order of arguments.
    667     * </p>
    668     * <p>
    669     * If the input iterable is {@code null}, the same is returned as for an empty iterable. If no predicates have been provided, all elements of the input
    670     * collection will be added to the rejected collection.
    671     * </p>
    672     * <p>
    673     * Example: for an input list [1, 2, 3, 4, 5] calling partition with predicates [x &lt; 3] and [x &lt; 5] will result in the following output: [[1, 2], [3,
    674     * 4], [5]].
    675     * </p>
    676     *
    677     * @param <O>              the type of object the {@link Iterable} contains.
    678     * @param <R>              the type of the output {@link Collection}.
    679     * @param iterable         The collection to get the input from, may be null.
    680     * @param partitionFactory The factory used to create the output collections.
    681     * @param predicates       The predicates to use, may not be null.
    682     * @return A list containing the output collections.
    683     * @throws NullPointerException if any predicate is null.
    684     */
    685    public static <O, R extends Collection<O>> List<R> partition(final Iterable<? extends O> iterable, final Factory<R> partitionFactory,
    686            final Predicate<? super O>... predicates) {
    687        if (iterable == null) {
    688            final Iterable<O> empty = emptyIterable();
    689            return partition(empty, partitionFactory, predicates);
    690        }
    691        Objects.requireNonNull(predicates, "predicates");
    692        for (final Predicate<?> predicate : predicates) {
    693            Objects.requireNonNull(predicate, "predicate");
    694        }
    695        if (predicates.length < 1) {
    696            // return the entire input collection as a single partition
    697            final R singlePartition = partitionFactory.get();
    698            CollectionUtils.addAll(singlePartition, iterable);
    699            return Collections.singletonList(singlePartition);
    700        }
    701        // create the empty partitions
    702        final int numberOfPredicates = predicates.length;
    703        final int numberOfPartitions = numberOfPredicates + 1;
    704        final List<R> partitions = new ArrayList<>(numberOfPartitions);
    705        for (int i = 0; i < numberOfPartitions; ++i) {
    706            partitions.add(partitionFactory.get());
    707        }
    708        // for each element in inputCollection:
    709        // find the first predicate that evaluates to true.
    710        // if there is a predicate, add the element to the corresponding partition.
    711        // if there is no predicate, add it to the last, catch-all partition.
    712        for (final O element : iterable) {
    713            boolean elementAssigned = false;
    714            for (int i = 0; i < numberOfPredicates; ++i) {
    715                if (predicates[i].test(element)) {
    716                    partitions.get(i).add(element);
    717                    elementAssigned = true;
    718                    break;
    719                }
    720            }
    721            if (!elementAssigned) {
    722                // no predicates evaluated to true
    723                // add element to last partition
    724                partitions.get(numberOfPredicates).add(element);
    725            }
    726        }
    727        return partitions;
    728    }
    729
    730    /**
    731     * Partitions all elements from iterable into separate output collections, based on the evaluation of the given predicate.
    732     * <p>
    733     * For each predicate, the result will contain a list holding all elements of the input iterable matching the predicate. The last list will hold all
    734     * elements which didn't match any predicate:
    735     * </p>
    736     *
    737     * <pre>
    738     *  [C1, R] = partition(I, P1) with
    739     *  I = input
    740     *  P1 = first predicate
    741     *  C1 = collection of elements matching P1
    742     *  R = collection of elements rejected by all predicates
    743     * </pre>
    744     * <p>
    745     * If the input iterable is {@code null}, the same is returned as for an empty iterable.
    746     * </p>
    747     * <p>
    748     * Example: for an input list [1, 2, 3, 4, 5] calling partition with a predicate [x &lt; 3] will result in the following output: [[1, 2], [3, 4, 5]].
    749     * </p>
    750     *
    751     * @param <O>       the type of object the {@link Iterable} contains.
    752     * @param iterable  The iterable to partition, may be null.
    753     * @param predicate The predicate to use, may not be null.
    754     * @return A list containing the output collections.
    755     * @throws NullPointerException if predicate is null.
    756     */
    757    public static <O> List<List<O>> partition(final Iterable<? extends O> iterable, final Predicate<? super O> predicate) {
    758        Objects.requireNonNull(predicate, "predicate");
    759        @SuppressWarnings({ "unchecked", "rawtypes" }) // safe
    760        final Factory<List<O>> factory = FactoryUtils.instantiateFactory((Class) ArrayList.class);
    761        @SuppressWarnings("unchecked") // safe
    762        final Predicate<? super O>[] predicates = new Predicate[] { predicate };
    763        return partition(iterable, factory, predicates);
    764    }
    765
    766    /**
    767     * Partitions all elements from iterable into separate output collections, based on the evaluation of the given predicates.
    768     * <p>
    769     * For each predicate, the result will contain a list holding all elements of the input iterable matching the predicate. The last list will hold all
    770     * elements which didn't match any predicate:
    771     * </p>
    772     *
    773     * <pre>
    774     *  [C1, C2, R] = partition(I, P1, P2) with
    775     *  I = input
    776     *  P1 = first predicate
    777     *  P2 = second predicate
    778     *  C1 = collection of elements matching P1
    779     *  C2 = collection of elements matching P2
    780     *  R = collection of elements rejected by all predicates
    781     * </pre>
    782     * <p>
    783     * <strong>Note</strong>: elements are only added to the output collection of the first matching predicate, determined by the order of arguments.
    784     * </p>
    785     * <p>
    786     * If the input iterable is {@code null}, the same is returned as for an empty iterable.
    787     * </p>
    788     * <p>
    789     * Example: for an input list [1, 2, 3, 4, 5] calling partition with predicates [x &lt; 3] and [x &lt; 5] will result in the following output: [[1, 2], [3,
    790     * 4], [5]].
    791     * </p>
    792     *
    793     * @param <O>        the type of object the {@link Iterable} contains.
    794     * @param iterable   The collection to get the input from, may be null.
    795     * @param predicates The predicates to use, may not be null.
    796     * @return A list containing the output collections.
    797     * @throws NullPointerException if any predicate is null.
    798     */
    799    public static <O> List<List<O>> partition(final Iterable<? extends O> iterable, final Predicate<? super O>... predicates) {
    800        @SuppressWarnings({ "unchecked", "rawtypes" }) // safe
    801        final Factory<List<O>> factory = FactoryUtils.instantiateFactory((Class) ArrayList.class);
    802        return partition(iterable, factory, predicates);
    803    }
    804
    805    /**
    806     * Returns a reversed view of the given iterable.
    807     * <p>
    808     * In case the provided iterable is a {@link List} instance, a {@link ReverseListIterator} will be used to reverse the traversal order, otherwise an
    809     * intermediate {@link List} needs to be created.
    810     * </p>
    811     * <p>
    812     * The returned iterable's iterator supports {@code remove()} if the provided iterable is a {@link List} instance.
    813     * </p>
    814     *
    815     * @param <E>      The element type.
    816     * @param iterable The iterable to use, may not be null.
    817     * @return A reversed view of the specified iterable.
    818     * @throws NullPointerException if iterable is null.
    819     * @see ReverseListIterator
    820     */
    821    public static <E> Iterable<E> reversedIterable(final Iterable<E> iterable) {
    822        Objects.requireNonNull(iterable, "iterable");
    823        return new FluentIterable<E>() {
    824
    825            @Override
    826            public Iterator<E> iterator() {
    827                final List<E> list = iterable instanceof List<?> ? (List<E>) iterable : IteratorUtils.toList(iterable.iterator());
    828                return new ReverseListIterator<>(list);
    829            }
    830        };
    831    }
    832
    833    /**
    834     * Returns the number of elements contained in the given iterator.
    835     * <p>
    836     * A {@code null} or empty iterator returns {@code 0}.
    837     * </p>
    838     *
    839     * @param iterable The iterable to check, may be null
    840     * @return The number of elements contained in the iterable
    841     */
    842    public static int size(final Iterable<?> iterable) {
    843        if (iterable == null) {
    844            return 0;
    845        }
    846        if (iterable instanceof Collection<?>) {
    847            return ((Collection<?>) iterable).size();
    848        }
    849        return IteratorUtils.size(emptyIteratorIfNull(iterable));
    850    }
    851
    852    /**
    853     * Returns a view of the given iterable that skips the first N elements.
    854     * <p>
    855     * The returned iterable's iterator supports {@code remove()} when the corresponding input iterator supports it.
    856     * </p>
    857     *
    858     * @param <E>            The element type.
    859     * @param iterable       The iterable to use, may not be null.
    860     * @param elementsToSkip The number of elements to skip from the start, must not be negative.
    861     * @return A view of the specified iterable, skipping the first N elements.
    862     * @throws IllegalArgumentException if elementsToSkip is negative.
    863     * @throws NullPointerException     if iterable is null.
    864     */
    865    public static <E> Iterable<E> skippingIterable(final Iterable<E> iterable, final long elementsToSkip) {
    866        Objects.requireNonNull(iterable, "iterable");
    867        if (elementsToSkip < 0) {
    868            throw new IllegalArgumentException("ElementsToSkip parameter must not be negative.");
    869        }
    870        return new FluentIterable<E>() {
    871
    872            @Override
    873            public Iterator<E> iterator() {
    874                return IteratorUtils.skippingIterator(iterable.iterator(), elementsToSkip);
    875            }
    876        };
    877    }
    878
    879    /**
    880     * Returns the sum of the sizes of the collections in the given iterable.
    881     * <p>
    882     * Integer overflow is capped at {@link Integer#MAX_VALUE}.
    883     * </p>
    884     *
    885     * @param <E>      The element type of the collections in the iterable.
    886     * @param iterable The iterable of collections to sum the sizes of, must not be null.
    887     * @return The sum of the sizes of the collections in the iterable, capped at {@link Integer#MAX_VALUE}.
    888     * @throws NullPointerException if iterable is null.
    889     * @since 4.6.0
    890     */
    891    public static <E> int sumSizesToInt(final Iterable<? extends Collection<E>> iterable) {
    892        return sumToInt(iterable, Collection::size);
    893    }
    894
    895    /**
    896     * Returns the sum of the integer values produced by applying the given function to each element in the iterable.
    897     * <p>
    898     * Integer overflow is capped at {@link Integer#MAX_VALUE}.
    899     * </p>
    900     *
    901     * @param <C>           The type of the elements in the iterable.
    902     * @param iterable      The iterable of elements to sum the integer values of, must not be null.
    903     * @param toIntFunction The function to apply to each element to produce an integer value, must not be null.
    904     * @return The sum of the integer values produced by applying the function to each element in the iterable, capped at {@link Integer#MAX_VALUE}.
    905     */
    906    private static <C extends Collection<?>> int sumToInt(final Iterable<C> iterable, final ToIntFunction<C> toIntFunction) {
    907        int size = 0;
    908        try {
    909            for (final C item : iterable) {
    910                if (item != null) {
    911                    size = Math.addExact(size, toIntFunction.applyAsInt(item));
    912                }
    913            }
    914        } catch (final ArithmeticException e) {
    915            size = Integer.MAX_VALUE;
    916        }
    917        return size;
    918    }
    919
    920    /**
    921     * Gets a new list with the contents of the provided iterable.
    922     *
    923     * @param <E>      The element type.
    924     * @param iterable The iterable to use, may be null.
    925     * @return A list of the iterator contents.
    926     */
    927    public static <E> List<E> toList(final Iterable<E> iterable) {
    928        return IteratorUtils.toList(emptyIteratorIfNull(iterable));
    929    }
    930
    931    /**
    932     * Returns a string representation of the elements of the specified iterable.
    933     * <p>
    934     * The string representation consists of a list of the iterable's elements, enclosed in square brackets ({@code "[]"}). Adjacent elements are separated by
    935     * the characters {@code ", "} (a comma followed by a space). Elements are converted to strings as by {@code String.valueOf(Object)}.
    936     * </p>
    937     *
    938     * @param <E>      The element type.
    939     * @param iterable The iterable to convert to a string, may be null.
    940     * @return A string representation of {@code iterable}.
    941     */
    942    public static <E> String toString(final Iterable<E> iterable) {
    943        return IteratorUtils.toString(emptyIteratorIfNull(iterable));
    944    }
    945
    946    /**
    947     * Returns a string representation of the elements of the specified iterable.
    948     * <p>
    949     * The string representation consists of a list of the iterable's elements, enclosed in square brackets ({@code "[]"}). Adjacent elements are separated by
    950     * the characters {@code ", "} (a comma followed by a space). Elements are converted to strings as by using the provided {@code transformer}.
    951     * </p>
    952     *
    953     * @param <E>         The element type
    954     * @param iterable    The iterable to convert to a string, may be null
    955     * @param transformer The transformer used to get a string representation of an element
    956     * @return A string representation of {@code iterable}
    957     * @throws NullPointerException if {@code transformer} is null
    958     */
    959    public static <E> String toString(final Iterable<E> iterable, final Transformer<? super E, String> transformer) {
    960        Objects.requireNonNull(transformer, "transformer");
    961        return IteratorUtils.toString(emptyIteratorIfNull(iterable), transformer);
    962    }
    963
    964    /**
    965     * Returns a string representation of the elements of the specified iterable.
    966     * <p>
    967     * The string representation consists of a list of the iterable's elements, enclosed by the provided {@code prefix} and {@code suffix}. Adjacent elements
    968     * are separated by the provided {@code delimiter}. Elements are converted to strings as by using the provided {@code transformer}.
    969     * </p>
    970     *
    971     * @param <E>         The element type.
    972     * @param iterable    The iterable to convert to a string, may be null.
    973     * @param transformer The transformer used to get a string representation of an element.
    974     * @param delimiter   The string to delimit elements.
    975     * @param prefix      The prefix, prepended to the string representation.
    976     * @param suffix      The suffix, appended to the string representation.
    977     * @return A string representation of {@code iterable}.
    978     * @throws NullPointerException if either transformer, delimiter, prefix or suffix is null.
    979     */
    980    public static <E> String toString(final Iterable<E> iterable, final Transformer<? super E, String> transformer, final String delimiter, final String prefix,
    981            final String suffix) {
    982        return IteratorUtils.toString(emptyIteratorIfNull(iterable), transformer, delimiter, prefix, suffix);
    983    }
    984
    985    /**
    986     * Returns a transformed view of the given iterable where all of its elements have been transformed by the provided transformer.
    987     * <p>
    988     * The returned iterable's iterator supports {@code remove()} when the corresponding input iterator supports it.
    989     * </p>
    990     *
    991     * @param <I>         the input element type.
    992     * @param <O>         the output element type.
    993     * @param iterable    The iterable to transform, may not be null.
    994     * @param transformer The transformer, must not be null.
    995     * @return A transformed view of the specified iterable.
    996     * @throws NullPointerException if either iterable or transformer is null.
    997     */
    998    public static <I, O> Iterable<O> transformedIterable(final Iterable<I> iterable, final Transformer<? super I, ? extends O> transformer) {
    999        Objects.requireNonNull(iterable, "iterable");
    1000        Objects.requireNonNull(transformer, "transformer");
    1001        return new FluentIterable<O>() {
    1002
    1003            @Override
    1004            public Iterator<O> iterator() {
    1005                return IteratorUtils.transformedIterator(iterable.iterator(), transformer);
    1006            }
    1007        };
    1008    }
    1009
    1010    /**
    1011     * Returns a unique view of the given iterable.
    1012     * <p>
    1013     * The returned iterable's iterator supports {@code remove()} when the corresponding input iterator supports it. Calling {@code remove()} will only remove a
    1014     * single element from the underlying iterator.
    1015     * </p>
    1016     *
    1017     * @param <E>      The element type.
    1018     * @param iterable The iterable to use, may not be null.
    1019     * @return A unique view of the specified iterable.
    1020     * @throws NullPointerException if iterable is null.
    1021     */
    1022    public static <E> Iterable<E> uniqueIterable(final Iterable<E> iterable) {
    1023        Objects.requireNonNull(iterable, "iterable");
    1024        return new FluentIterable<E>() {
    1025
    1026            @Override
    1027            public Iterator<E> iterator() {
    1028                return new UniqueFilterIterator<>(iterable.iterator());
    1029            }
    1030        };
    1031    }
    1032
    1033    /**
    1034     * Returns an unmodifiable view of the given iterable.
    1035     * <p>
    1036     * The returned iterable's iterator does not support {@code remove()}.
    1037     * </p>
    1038     *
    1039     * @param <E>      The element type.
    1040     * @param iterable The iterable to use, may not be null.
    1041     * @return An unmodifiable view of the specified iterable.
    1042     * @throws NullPointerException if iterable is null.
    1043     */
    1044    public static <E> Iterable<E> unmodifiableIterable(final Iterable<E> iterable) {
    1045        Objects.requireNonNull(iterable, "iterable");
    1046        if (iterable instanceof UnmodifiableIterable<?>) {
    1047            return iterable;
    1048        }
    1049        return new UnmodifiableIterable<>(iterable);
    1050    }
    1051
    1052    /**
    1053     * Interleaves two iterables into a single iterable.
    1054     * <p>
    1055     * 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
    1056     * until necessary.
    1057     * </p>
    1058     * <p>
    1059     * The returned iterable's iterator supports {@code remove()} when the corresponding input iterator supports it.
    1060     * </p>
    1061     *
    1062     * @param <E> The element type.
    1063     * @param a   The first iterable, may not be null.
    1064     * @param b   The second iterable, may not be null.
    1065     * @return A new iterable, interleaving the provided iterables.
    1066     * @throws NullPointerException if either a or b is null.
    1067     */
    1068    public static <E> Iterable<E> zippingIterable(final Iterable<? extends E> a, final Iterable<? extends E> b) {
    1069        Objects.requireNonNull(a, "iterable");
    1070        Objects.requireNonNull(b, "iterable");
    1071        return new FluentIterable<E>() {
    1072
    1073            @Override
    1074            public Iterator<E> iterator() {
    1075                return IteratorUtils.zippingIterator(a.iterator(), b.iterator());
    1076            }
    1077        };
    1078    }
    1079
    1080    /**
    1081     * Interleaves two iterables into a single iterable.
    1082     * <p>
    1083     * 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
    1084     * until necessary.
    1085     * </p>
    1086     * <p>
    1087     * The returned iterable's iterator supports {@code remove()} when the corresponding input iterator supports it.
    1088     * </p>
    1089     *
    1090     * @param <E>    the element type.
    1091     * @param first  The first iterable, may not be null.
    1092     * @param others The array of iterables to interleave, may not be null.
    1093     * @return A new iterable, interleaving the provided iterables.
    1094     * @throws NullPointerException if either of the provided iterables is null.
    1095     */
    1096    public static <E> Iterable<E> zippingIterable(final Iterable<? extends E> first, final Iterable<? extends E>... others) {
    1097        Objects.requireNonNull(first, "iterable");
    1098        checkNotNull(others);
    1099        return new FluentIterable<E>() {
    1100
    1101            @Override
    1102            public Iterator<E> iterator() {
    1103                @SuppressWarnings("unchecked") // safe
    1104                final Iterator<? extends E>[] iterators = new Iterator[others.length + 1];
    1105                iterators[0] = first.iterator();
    1106                for (int i = 0; i < others.length; i++) {
    1107                    iterators[i + 1] = others[i].iterator();
    1108                }
    1109                return IteratorUtils.zippingIterator(iterators);
    1110            }
    1111        };
    1112    }
    1113
    1114    /**
    1115     * Make private in 5.0.
    1116     *
    1117     * @deprecated TODO Make private in 5.0.
    1118     */
    1119    @Deprecated
    1120    public IterableUtils() {
    1121        // empty
    1122    }
    1123}