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