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}