    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 */
    017package org.apache.commons.collections4;
    018
    019import java.lang.reflect.Array;
    020import java.util.ArrayList;
    021import java.util.Collection;
    022import java.util.Collections;
    023import java.util.Comparator;
    024import java.util.Enumeration;
    025import java.util.HashMap;
    026import java.util.HashSet;
    027import java.util.Iterator;
    028import java.util.List;
    029import java.util.ListIterator;
    030import java.util.Map;
    031import java.util.Objects;
    032import java.util.Set;
    033
    034import org.apache.commons.collections4.collection.PredicatedCollection;
    035import org.apache.commons.collections4.collection.SynchronizedCollection;
    036import org.apache.commons.collections4.collection.TransformedCollection;
    037import org.apache.commons.collections4.collection.UnmodifiableBoundedCollection;
    038import org.apache.commons.collections4.collection.UnmodifiableCollection;
    039import org.apache.commons.collections4.functors.TruePredicate;
    040import org.apache.commons.collections4.iterators.CollatingIterator;
    041import org.apache.commons.collections4.iterators.PermutationIterator;
    042import org.apache.commons.collections4.multiset.HashMultiSet;
    043
    044/**
    045 * Provides utility methods and decorators for {@link Collection} instances.
    046 * <p>
    047 * Various utility methods might put the input objects into a Set/Map/MultiSet. In case the input objects override {@link Object#equals(Object)}, it is
    048 * mandatory that the general contract of the {@link Object#hashCode()} method is maintained.
    049 * </p>
    050 * <p>
    051 * NOTE: From 4.0, method parameters will take {@link Iterable} objects when possible.
    052 * </p>
    053 *
    054 * @since 1.0
    055 */
    056public class CollectionUtils {
    057
    058    /**
    059     * Helper class to easily access cardinality properties of two collections.
    060     *
    061     * @param <O> the element type.
    062     */
    063    private static class CardinalityHelper<O> {
    064
    065        static boolean equals(final Collection<?> a, final Collection<?> b) {
    066            return new HashMultiSet<>(a).equals(new HashMultiSet<>(b));
    067        }
    068
    069        /** Contains the cardinality for each object in collection A. */
    070        final MultiSet<O> cardinalityA;
    071
    072        /** Contains the cardinality for each object in collection B. */
    073        final MultiSet<O> cardinalityB;
    074
    075        /**
    076         * Creates a new CardinalityHelper for two collections.
    077         *
    078         * @param a The first collection.
    079         * @param b The second collection.
    080         */
    081        CardinalityHelper(final Iterable<? extends O> a, final Iterable<? extends O> b) {
    082            cardinalityA = new HashMultiSet<>(a);
    083            cardinalityB = new HashMultiSet<>(b);
    084        }
    085
    086        /**
    087         * Gets the frequency of this object in collection A.
    088         *
    089         * @param key The key whose associated frequency is to be returned.
    090         * @return The frequency of the object in collection A.
    091         */
    092        public int freqA(final Object key) {
    093            return getFreq(key, cardinalityA);
    094        }
    095
    096        /**
    097         * Gets the frequency of this object in collection B.
    098         *
    099         * @param key The key whose associated frequency is to be returned.
    100         * @return The frequency of the object in collection B.
    101         */
    102        public int freqB(final Object key) {
    103            return getFreq(key, cardinalityB);
    104        }
    105
    106        private int getFreq(final Object key, final MultiSet<?> freqMap) {
    107            return freqMap.getCount(key);
    108        }
    109
    110        /**
    111         * Gets the maximum frequency of an object.
    112         *
    113         * @param obj The object.
    114         * @return The maximum frequency of the object.
    115         */
    116        public final int max(final Object obj) {
    117            return Math.max(freqA(obj), freqB(obj));
    118        }
    119
    120        /**
    121         * Gets the minimum frequency of an object.
    122         *
    123         * @param obj The object.
    124         * @return The minimum frequency of the object.
    125         */
    126        public final int min(final Object obj) {
    127            return Math.min(freqA(obj), freqB(obj));
    128        }
    129    }
    130
    131    /**
    132     * Wraps another object and uses the provided Equator to implement {@link #equals(Object)} and {@link #hashCode()}.
    133     * <p>
    134     * This class can be used to store objects into a Map.
    135     * </p>
    136     *
    137     * @param <O> the element type.
    138     * @since 4.0
    139     */
    140    private static final class EquatorWrapper<O> {
    141
    142        private final Equator<? super O> equator;
    143
    144        private final O object;
    145
    146        EquatorWrapper(final Equator<? super O> equator, final O object) {
    147            this.equator = equator;
    148            this.object = object;
    149        }
    150
    151        @Override
    152        public boolean equals(final Object obj) {
    153            if (!(obj instanceof EquatorWrapper)) {
    154                return false;
    155            }
    156            @SuppressWarnings("unchecked")
    157            final EquatorWrapper<O> otherObj = (EquatorWrapper<O>) obj;
    158            return equator.equate(object, otherObj.getObject());
    159        }
    160
    161        public O getObject() {
    162            return object;
    163        }
    164
    165        @Override
    166        public int hashCode() {
    167            return equator.hash(object);
    168        }
    169    }
    170
    171    /**
    172     * Helper class for set-related operations, for example union, subtract, intersection.
    173     *
    174     * @param <O> the element type.
    175     */
    176    private static final class SetOperationCardinalityHelper<O> extends CardinalityHelper<O> implements Iterable<O> {
    177
    178        /** Contains the unique elements of the two collections. */
    179        private final Set<O> elements;
    180
    181        /** Output collection. */
    182        private final List<O> newList;
    183
    184        /**
    185         * Create a new set operation helper from the two collections.
    186         *
    187         * @param a The first collection.
    188         * @param b The second collection.
    189         */
    190        SetOperationCardinalityHelper(final Iterable<? extends O> a, final Iterable<? extends O> b) {
    191            super(a, b);
    192            elements = new HashSet<>();
    193            addAll(elements, a);
    194            addAll(elements, b);
    195            // the resulting list must contain at least each unique element, but may grow
    196            newList = new ArrayList<>(elements.size());
    197        }
    198
    199        @Override
    200        public Iterator<O> iterator() {
    201            return elements.iterator();
    202        }
    203
    204        /**
    205         * Returns the resulting collection.
    206         *
    207         * @return The result.
    208         */
    209        public Collection<O> list() {
    210            return newList;
    211        }
    212
    213        /**
    214         * Add the object {@code count} times to the result collection.
    215         *
    216         * @param obj   The object to add.
    217         * @param count The count.
    218         */
    219        public void setCardinality(final O obj, final int count) {
    220            for (int i = 0; i < count; i++) {
    221                newList.add(obj);
    222            }
    223        }
    224    }
    225
    226    /**
    227     * The index value when an element is not found in a collection or array: {@code -1}.
    228     *
    229     * @since 4.5.0-M1
    230     */
    231    public static final int INDEX_NOT_FOUND = -1;
    232
    233    /**
    234     * Default prefix used while converting an Iterator to its String representation.
    235     *
    236     * @since 4.5.0-M1
    237     */
    238    public static final String DEFAULT_TOSTRING_PREFIX = "[";
    239
    240    /**
    241     * Default suffix used while converting an Iterator to its String representation.
    242     *
    243     * @since 4.5.0-M1
    244     */
    245    public static final String DEFAULT_TOSTRING_SUFFIX = "]";
    246
    247    /**
    248     * A String for Colon  (":").
    249     *
    250     * @since 4.5.0-M1
    251     */
    252    public static final String COLON = ":";
    253
    254    /**
    255     * A String for Comma (",").
    256     *
    257     * @since 4.5.0-M1
    258     */
    259    public static final String COMMA = ",";
    260
    261    /**
    262     * An empty unmodifiable collection. The JDK provides empty Set and List implementations which could be used for this purpose. However they could be cast to
    263     * Set or List which might be undesirable. This implementation only implements Collection.
    264     */
    265    @SuppressWarnings("rawtypes") // we deliberately use the raw type here
    266    public static final Collection EMPTY_COLLECTION = Collections.emptyList();
    267
    268    /**
    269     * Adds all elements in the array to the given collection.
    270     *
    271     * @param <C>        the type of object the {@link Collection} contains.
    272     * @param collection The collection to add to, must not be null.
    273     * @param elements   The array of elements to add, must not be null.
    274     * @return {@code true} if the collection was changed, {@code false} otherwise.
    275     * @throws NullPointerException if the collection or elements is null.
    276     */
    277    public static <C> boolean addAll(final Collection<C> collection, final C... elements) {
    278        Objects.requireNonNull(collection, "collection");
    279        Objects.requireNonNull(elements, "elements");
    280        boolean changed = false;
    281        for (final C element : elements) {
    282            changed |= collection.add(element);
    283        }
    284        return changed;
    285    }
    286
    287    /**
    288     * Adds all elements in the enumeration to the given collection.
    289     *
    290     * @param <C>         the type of object the {@link Collection} contains.
    291     * @param collection  The collection to add to, must not be null.
    292     * @param enumeration The enumeration of elements to add, must not be null.
    293     * @return {@code true} if the collections was changed, {@code false} otherwise.
    294     * @throws NullPointerException if the collection or enumeration is null.
    295     */
    296    public static <C> boolean addAll(final Collection<C> collection, final Enumeration<? extends C> enumeration) {
    297        Objects.requireNonNull(collection, "collection");
    298        Objects.requireNonNull(enumeration, "enumeration");
    299        boolean changed = false;
    300        while (enumeration.hasMoreElements()) {
    301            changed |= collection.add(enumeration.nextElement());
    302        }
    303        return changed;
    304    }
    305
    306    /**
    307     * Adds all elements in the {@link Iterable} to the given collection. If the {@link Iterable} is a {@link Collection} then it is cast and will be added
    308     * using {@link Collection#addAll(Collection)} instead of iterating.
    309     *
    310     * @param <C>        the type of object the {@link Collection} contains.
    311     * @param collection The collection to add to, must not be null.
    312     * @param iterable   The iterable of elements to add, must not be null.
    313     * @return A boolean indicating whether the collection has changed or not.
    314     * @throws NullPointerException if the collection or iterable is null.
    315     */
    316    public static <C> boolean addAll(final Collection<C> collection, final Iterable<? extends C> iterable) {
    317        Objects.requireNonNull(collection, "collection");
    318        Objects.requireNonNull(iterable, "iterable");
    319        if (iterable instanceof Collection<?>) {
    320            return collection.addAll((Collection<? extends C>) iterable);
    321        }
    322        return addAll(collection, iterable.iterator());
    323    }
    324
    325    /**
    326     * Adds all elements in the iteration to the given collection.
    327     *
    328     * @param <C>        the type of object the {@link Collection} contains.
    329     * @param collection The collection to add to, must not be null.
    330     * @param iterator   The iterator of elements to add, must not be null.
    331     * @return A boolean indicating whether the collection has changed or not.
    332     * @throws NullPointerException if the collection or iterator is null.
    333     */
    334    public static <C> boolean addAll(final Collection<C> collection, final Iterator<? extends C> iterator) {
    335        Objects.requireNonNull(collection, "collection");
    336        Objects.requireNonNull(iterator, "iterator");
    337        boolean changed = false;
    338        while (iterator.hasNext()) {
    339            changed |= collection.add(iterator.next());
    340        }
    341        return changed;
    342    }
    343
    344    /**
    345     * Adds an element to the collection unless the element is null.
    346     *
    347     * @param <T>        the type of object the {@link Collection} contains.
    348     * @param collection The collection to add to, must not be null.
    349     * @param object     The object to add, if null it will not be added.
    350     * @return true if the collection changed.
    351     * @throws NullPointerException if the collection is null.
    352     * @since 3.2
    353     */
    354    public static <T> boolean addIgnoreNull(final Collection<T> collection, final T object) {
    355        Objects.requireNonNull(collection, "collection");
    356        return object != null && collection.add(object);
    357    }
    358
    359    /**
    360     * Returns the number of occurrences of <em>obj</em> in <em>coll</em>.
    361     *
    362     * @param obj        The object to find the cardinality of.
    363     * @param collection The {@link Iterable} to search.
    364     * @param <O>        The type of object that the {@link Iterable} may contain.
    365     * @return The number of occurrences of obj in coll.
    366     * @throws NullPointerException if collection is null.
    367     * @deprecated Since 4.1, use {@link IterableUtils#frequency(Iterable, Object)} instead. Be aware that the order of parameters has changed.
    368     */
    369    @Deprecated
    370    public static <O> int cardinality(final O obj, final Iterable<? super O> collection) {
    371        return IterableUtils.frequency(Objects.requireNonNull(collection, "collection"), obj);
    372    }
    373
    374    /**
    375     * Ensures an index is not negative.
    376     *
    377     * @param index The index to check.
    378     * @throws IndexOutOfBoundsException if the index is negative.
    379     */
    380    static void checkIndexBounds(final int index) {
    381        if (index < 0) {
    382            throw new IndexOutOfBoundsException("Index cannot be negative: " + index);
    383        }
    384    }
    385
    386    /**
    387     * Merges two sorted Collections, a and b, into a single, sorted List such that the natural ordering of the elements is retained.
    388     * <p>
    389     * Uses the standard O(n) merge algorithm for combining two sorted lists.
    390     * </p>
    391     *
    392     * @param <O> the element type.
    393     * @param a   The first collection, must not be null.
    394     * @param b   The second collection, must not be null.
    395     * @return A new sorted List, containing the elements of Collection a and b.
    396     * @throws NullPointerException if either collection is null.
    397     * @since 4.0
    398     */
    399    public static <O extends Comparable<? super O>> List<O> collate(final Iterable<? extends O> a, final Iterable<? extends O> b) {
    400        return collate(a, b, ComparatorUtils.<O>naturalComparator(), true);
    401    }
    402
    403    /**
    404     * Merges two sorted Collections, a and b, into a single, sorted List such that the natural ordering of the elements is retained.
    405     * <p>
    406     * Uses the standard O(n) merge algorithm for combining two sorted lists.
    407     * </p>
    408     *
    409     * @param <O>               the element type.
    410     * @param a                 The first collection, must not be null.
    411     * @param b                 The second collection, must not be null.
    412     * @param includeDuplicates if {@code true} duplicate elements will be retained, otherwise they will be removed in the output collection.
    413     * @return A new sorted List, containing the elements of Collection a and b.
    414     * @throws NullPointerException if either collection is null.
    415     * @since 4.0
    416     */
    417    public static <O extends Comparable<? super O>> List<O> collate(final Iterable<? extends O> a, final Iterable<? extends O> b,
    418            final boolean includeDuplicates) {
    419        return collate(a, b, ComparatorUtils.<O>naturalComparator(), includeDuplicates);
    420    }
    421
    422    /**
    423     * Merges two sorted Collections, a and b, into a single, sorted List such that the ordering of the elements according to Comparator c is retained.
    424     * <p>
    425     * Uses the standard O(n) merge algorithm for combining two sorted lists.
    426     * </p>
    427     *
    428     * @param <O> the element type.
    429     * @param a   The first collection, must not be null.
    430     * @param b   The second collection, must not be null.
    431     * @param c   The comparator to use for the merge.
    432     * @return A new sorted List, containing the elements of Collection a and b.
    433     * @throws NullPointerException if either collection or the comparator is null.
    434     * @since 4.0
    435     */
    436    public static <O> List<O> collate(final Iterable<? extends O> a, final Iterable<? extends O> b, final Comparator<? super O> c) {
    437        return collate(a, b, c, true);
    438    }
    439
    440    /**
    441     * Merges two sorted Collections, a and b, into a single, sorted List such that the ordering of the elements according to Comparator c is retained.
    442     * <p>
    443     * Uses the standard O(n) merge algorithm for combining two sorted lists.
    444     * </p>
    445     *
    446     * @param <O>               the element type.
    447     * @param iterableA         The first collection, must not be null.
    448     * @param iterableB         The second collection, must not be null.
    449     * @param comparator        The comparator to use for the merge.
    450     * @param includeDuplicates if {@code true} duplicate elements will be retained, otherwise they will be removed in the output collection.
    451     * @return A new sorted List, containing the elements of Collection a and b.
    452     * @throws NullPointerException if either collection or the comparator is null.
    453     * @since 4.0
    454     */
    455    public static <O> List<O> collate(final Iterable<? extends O> iterableA, final Iterable<? extends O> iterableB, final Comparator<? super O> comparator,
    456            final boolean includeDuplicates) {
    457        Objects.requireNonNull(iterableA, "iterableA");
    458        Objects.requireNonNull(iterableB, "iterableB");
    459        Objects.requireNonNull(comparator, "comparator");
    460        // if both Iterables are a Collection, we can estimate the size
    461        final int totalSize = iterableA instanceof Collection<?> && iterableB instanceof Collection<?>
    462                ? Math.max(1, ((Collection<?>) iterableA).size() + ((Collection<?>) iterableB).size())
    463                : 10;
    464        final Iterator<O> iterator = new CollatingIterator<>(comparator, iterableA.iterator(), iterableB.iterator());
    465        if (includeDuplicates) {
    466            return IteratorUtils.toList(iterator, totalSize);
    467        }
    468        final ArrayList<O> mergedList = new ArrayList<>(totalSize);
    469        O lastItem = null;
    470        boolean first = true;
    471        while (iterator.hasNext()) {
    472            final O item = iterator.next();
    473            if (first || !Objects.equals(lastItem, item)) {
    474                mergedList.add(item);
    475            }
    476            lastItem = item;
    477            first = false;
    478        }
    479        mergedList.trimToSize();
    480        return mergedList;
    481    }
    482
    483    /**
    484     * Transforms all elements from input collection with the given transformer and adds them to the output collection.
    485     * <p>
    486     * If the input collection or transformer is null, there is no change to the output collection.
    487     * </p>
    488     *
    489     * @param <I>              the type of object in the input collection.
    490     * @param <O>              the type of object in the output collection.
    491     * @param <R>              the type of the output collection.
    492     * @param inputCollection  The collection to get the input from, may be null.
    493     * @param transformer      The transformer to use, may be null.
    494     * @param outputCollection The collection to output into, may not be null if inputCollection and transformer are not null.
    495     * @return The output collection with the transformed input added.
    496     * @throws NullPointerException if the outputCollection is null and both, inputCollection and transformer are not null.
    497     */
    498    public static <I, O, R extends Collection<? super O>> R collect(final Iterable<? extends I> inputCollection,
    499            final Transformer<? super I, ? extends O> transformer, final R outputCollection) {
    500        if (inputCollection != null) {
    501            return collect(inputCollection.iterator(), transformer, outputCollection);
    502        }
    503        return outputCollection;
    504    }
    505
    506    /**
    507     * Returns a new Collection containing all elements of the input collection transformed by the given transformer.
    508     * <p>
    509     * If the input collection or transformer is null, the result is an empty list.
    510     * </p>
    511     *
    512     * @param <I>             the type of object in the input collection.
    513     * @param <O>             the type of object in the output collection.
    514     * @param inputCollection The collection to get the input from, may not be null.
    515     * @param transformer     The transformer to use, may be null.
    516     * @return The transformed result (new list).
    517     * @throws NullPointerException if the outputCollection is null and both, inputCollection and transformer are not null.
    518     */
    519    public static <I, O> Collection<O> collect(final Iterable<I> inputCollection, final Transformer<? super I, ? extends O> transformer) {
    520        int size = 0;
    521        if (inputCollection != null) {
    522            size = inputCollection instanceof Collection<?> ? ((Collection<?>) inputCollection).size() : 0;
    523        }
    524        final Collection<O> answer = size == 0 ? new ArrayList<>() : new ArrayList<>(size);
    525        return collect(inputCollection, transformer, answer);
    526    }
    527
    528    /**
    529     * Transforms all elements from the input iterator with the given transformer and adds them to the output collection.
    530     * <p>
    531     * If the input iterator or transformer is null, there is no change to the output collection.
    532     * </p>
    533     *
    534     * @param <I>              the type of object in the input collection.
    535     * @param <O>              the type of object in the output collection.
    536     * @param <R>              the type of the output collection.
    537     * @param inputIterator    The iterator to get the input from, may be null.
    538     * @param transformer      The transformer to use, may be null.
    539     * @param outputCollection The collection to output into, may not be null if inputIterator and transformer are not null.
    540     * @return The outputCollection with the transformed input added.
    541     * @throws NullPointerException if the output collection is null and both, inputIterator and transformer are not null.
    542     */
    543    public static <I, O, R extends Collection<? super O>> R collect(final Iterator<? extends I> inputIterator,
    544            final Transformer<? super I, ? extends O> transformer, final R outputCollection) {
    545        if (inputIterator != null && transformer != null) {
    546            while (inputIterator.hasNext()) {
    547                final I item = inputIterator.next();
    548                final O value = transformer.apply(item);
    549                outputCollection.add(value);
    550            }
    551        }
    552        return outputCollection;
    553    }
    554
    555    /**
    556     * Transforms all elements from the input iterator with the given transformer and adds them to the output collection.
    557     * <p>
    558     * If the input iterator or transformer is null, the result is an empty list.
    559     * </p>
    560     *
    561     * @param <I>           the type of object in the input collection.
    562     * @param <O>           the type of object in the output collection.
    563     * @param inputIterator The iterator to get the input from, may be null.
    564     * @param transformer   The transformer to use, may be null.
    565     * @return The transformed result (new list).
    566     */
    567    public static <I, O> Collection<O> collect(final Iterator<I> inputIterator, final Transformer<? super I, ? extends O> transformer) {
    568        return collect(inputIterator, transformer, new ArrayList<>());
    569    }
    570
    571    /**
    572     * Returns {@code true} iff all elements of {@code coll2} are also contained in {@code coll1}. The cardinality of values in {@code coll2} is not taken into
    573     * account, which is the same behavior as {@link Collection#containsAll(Collection)}.
    574     * <p>
    575     * In other words, this method returns {@code true} iff the {@link #intersection} of <em>coll1</em> and <em>coll2</em> has the same cardinality as the set
    576     * of unique values from {@code coll2}. In case {@code coll2} is empty, {@code true} will be returned.
    577     * </p>
    578     * <p>
    579     * This method is intended as a replacement for {@link Collection#containsAll(Collection)} with a guaranteed runtime complexity of {@code O(n + m)}.
    580     * Depending on the type of {@link Collection} provided, this method will be much faster than calling {@link Collection#containsAll(Collection)} instead,
    581     * though this will come at the cost of an additional space complexity O(n).
    582     * </p>
    583     *
    584     * @param coll1 The first collection, must not be null.
    585     * @param coll2 The second collection, must not be null.
    586     * @return {@code true} iff the intersection of the collections has the same cardinality as the set of unique elements from the second collection.
    587     * @throws NullPointerException if coll1 or coll2 is null.
    588     * @since 4.0
    589     */
    590    public static boolean containsAll(final Collection<?> coll1, final Collection<?> coll2) {
    591        Objects.requireNonNull(coll1, "coll1");
    592        Objects.requireNonNull(coll2, "coll2");
    593        if (coll2.isEmpty()) {
    594            return true;
    595        }
    596        final Set<Object> elementsAlreadySeen = new HashSet<>();
    597        for (final Object nextElement : coll2) {
    598            if (elementsAlreadySeen.contains(nextElement)) {
    599                continue;
    600            }
    601            boolean foundCurrentElement = false;
    602            for (final Object p : coll1) {
    603                elementsAlreadySeen.add(p);
    604                if (Objects.equals(nextElement, p)) {
    605                    foundCurrentElement = true;
    606                    break;
    607                }
    608            }
    609            if (!foundCurrentElement) {
    610                return false;
    611            }
    612        }
    613        return true;
    614    }
    615
    616    /**
    617     * Returns {@code true} iff at least one element is in both collections.
    618     * <p>
    619     * In other words, this method returns {@code true} iff the {@link #intersection} of <em>coll1</em> and <em>coll2</em> is not empty.
    620     * </p>
    621     *
    622     * @param coll1 The first collection, must not be null.
    623     * @param coll2 The second collection, must not be null.
    624     * @return {@code true} iff the intersection of the collections is non-empty.
    625     * @throws NullPointerException if coll1 or coll2 is null.
    626     * @since 2.1
    627     * @see #intersection
    628     */
    629    public static boolean containsAny(final Collection<?> coll1, final Collection<?> coll2) {
    630        Objects.requireNonNull(coll1, "coll1");
    631        Objects.requireNonNull(coll2, "coll2");
    632        if (coll1.size() < coll2.size()) {
    633            for (final Object aColl1 : coll1) {
    634                if (coll2.contains(aColl1)) {
    635                    return true;
    636                }
    637            }
    638        } else {
    639            for (final Object aColl2 : coll2) {
    640                if (coll1.contains(aColl2)) {
    641                    return true;
    642                }
    643            }
    644        }
    645        return false;
    646    }
    647
    648    /**
    649     * Returns {@code true} iff at least one element is in both collections.
    650     * <p>
    651     * In other words, this method returns {@code true} iff the {@link #intersection} of <em>coll1</em> and <em>coll2</em> is not empty.
    652     * </p>
    653     *
    654     * @param <T>   The type of object to lookup in {@code coll1}.
    655     * @param coll1 The first collection, must not be {@code null}.
    656     * @param coll2 The second collection, must not be {@code null}.
    657     * @return {@code true} iff the intersection of the collections is non-empty.
    658     * @throws NullPointerException if coll1 or coll2 is {@code null}.
    659     * @since 4.2
    660     * @see #intersection
    661     */
    662    public static <T> boolean containsAny(final Collection<?> coll1, @SuppressWarnings("unchecked") final T... coll2) {
    663        Objects.requireNonNull(coll1, "coll1");
    664        Objects.requireNonNull(coll2, "coll2");
    665        if (coll1.size() < coll2.length) {
    666            for (final Object aColl1 : coll1) {
    667                if (ArrayUtils.contains(coll2, aColl1)) {
    668                    return true;
    669                }
    670            }
    671        } else {
    672            for (final Object aColl2 : coll2) {
    673                if (coll1.contains(aColl2)) {
    674                    return true;
    675                }
    676            }
    677        }
    678        return false;
    679    }
    680
    681    /**
    682     * Counts the number of elements in the input collection that match the predicate.
    683     * <p>
    684     * A {@code null} collection or predicate matches no elements.
    685     * </p>
    686     *
    687     * @param <C>       the type of object the {@link Iterable} contains.
    688     * @param input     The {@link Iterable} to get the input from, may be null.
    689     * @param predicate The predicate to use, may be null.
    690     * @return The number of matches for the predicate in the collection.
    691     * @deprecated Since 4.1, use {@link IterableUtils#countMatches(Iterable, Predicate)} instead.
    692     */
    693    @Deprecated
    694    public static <C> int countMatches(final Iterable<C> input, final Predicate<? super C> predicate) {
    695        return predicate == null ? 0 : (int) IterableUtils.countMatches(input, predicate);
    696    }
    697
    698    /**
    699     * Returns a {@link Collection} containing the exclusive disjunction (symmetric difference) of the given {@link Iterable}s.
    700     * <p>
    701     * The cardinality of each element <em>e</em> in the returned {@link Collection} will be equal to
    702     * <code>max(cardinality(<em>e</em>,<em>a</em>),cardinality(<em>e</em>,<em>b</em>)) - min(cardinality(<em>e</em>,<em>a</em>),
    703     * cardinality(<em>e</em>,<em>b</em>))</code>.
    704     * </p>
    705     * <p>
    706     * This is equivalent to {@code {@link #subtract subtract}({@link #union union(a, b)},{@link #intersection intersection(a, b)})} or
    707     * {@code {@link #union union}({@link #subtract subtract(a, b)},{@link #subtract subtract(b, a)})}.
    708     * </p>
    709     *
    710     * @param a   The first collection, must not be null.
    711     * @param b   The second collection, must not be null.
    712     * @param <O> The generic type that is able to represent the types contained in both input collections.
    713     * @return The symmetric difference of the two collections.
    714     * @throws NullPointerException if either collection is null.
    715     */
    716    public static <O> Collection<O> disjunction(final Iterable<? extends O> a, final Iterable<? extends O> b) {
    717        Objects.requireNonNull(a, "a");
    718        Objects.requireNonNull(b, "b");
    719        final SetOperationCardinalityHelper<O> helper = new SetOperationCardinalityHelper<>(a, b);
    720        for (final O obj : helper) {
    721            helper.setCardinality(obj, helper.max(obj) - helper.min(obj));
    722        }
    723        return helper.list();
    724    }
    725
    726    /**
    727     * Returns the immutable EMPTY_COLLECTION with generic type safety.
    728     *
    729     * @param <T> The element type.
    730     * @return immutable empty collection.
    731     * @see #EMPTY_COLLECTION
    732     * @since 4.0
    733     */
    734    @SuppressWarnings("unchecked") // OK, empty collection is compatible with any type
    735    public static <T> Collection<T> emptyCollection() {
    736        return EMPTY_COLLECTION;
    737    }
    738
    739    /**
    740     * Returns an immutable empty collection if the argument is {@code null}, or the argument itself otherwise.
    741     *
    742     * @param <T>        The element type.
    743     * @param collection The collection, possibly {@code null}.
    744     * @return An empty collection if the argument is {@code null}.
    745     */
    746    public static <T> Collection<T> emptyIfNull(final Collection<T> collection) {
    747        return collection == null ? emptyCollection() : collection;
    748    }
    749
    750    /**
    751     * Answers true if a predicate is true for at least one element of a collection.
    752     * <p>
    753     * A {@code null} collection or predicate returns false.
    754     * </p>
    755     *
    756     * @param <C>       the type of object the {@link Iterable} contains.
    757     * @param input     The {@link Iterable} to get the input from, may be null.
    758     * @param predicate The predicate to use, may be null.
    759     * @return true if at least one element of the collection matches the predicate.
    760     * @deprecated Since 4.1, use {@link IterableUtils#matchesAny(Iterable, Predicate)} instead.
    761     */
    762    @Deprecated
    763    public static <C> boolean exists(final Iterable<C> input, final Predicate<? super C> predicate) {
    764        return predicate != null && IterableUtils.matchesAny(input, predicate);
    765    }
    766
    767    /**
    768     * Extract the lone element of the specified Collection.
    769     *.
    770     * @param <E>        collection type
    771     * @param collection to read.
    772     * @return sole member of collection.
    773     * @throws NullPointerException     if collection is null.
    774     * @throws IllegalArgumentException if collection is empty or contains more than one element.
    775     * @since 4.0
    776     */
    777    public static <E> E extractSingleton(final Collection<E> collection) {
    778        Objects.requireNonNull(collection, "collection");
    779        if (collection.size() != 1) {
    780            throw new IllegalArgumentException("Can extract singleton only when collection size == 1");
    781        }
    782        return collection.iterator().next();
    783    }
    784
    785    /**
    786     * Filter the collection by applying a Predicate to each element. If the predicate returns false, remove the element.
    787     * <p>
    788     * If the input collection or predicate is null, there is no change made.
    789     * </p>
    790     *
    791     * @param <T>        the type of object the {@link Iterable} contains.
    792     * @param collection The collection to get the input from, may be null.
    793     * @param predicate  The predicate to use as a filter, may be null.
    794     * @return true if the collection is modified by this call, false otherwise.
    795     */
    796    public static <T> boolean filter(final Iterable<T> collection, final Predicate<? super T> predicate) {
    797        boolean result = false;
    798        if (collection != null && predicate != null) {
    799            for (final Iterator<T> it = collection.iterator(); it.hasNext();) {
    800                if (!predicate.test(it.next())) {
    801                    it.remove();
    802                    result = true;
    803                }
    804            }
    805        }
    806        return result;
    807    }
    808
    809    /**
    810     * Filter the collection by applying a Predicate to each element. If the predicate returns true, remove the element.
    811     * <p>
    812     * This is equivalent to {@code filter(collection, PredicateUtils.notPredicate(predicate))} if predicate is != null.
    813     * </p>
    814     * <p>
    815     * If the input collection or predicate is null, there is no change made.
    816     * </p>
    817     *
    818     * @param <T>        the type of object the {@link Iterable} contains.
    819     * @param collection The collection to get the input from, may be null.
    820     * @param predicate  The predicate to use as a filter, may be null.
    821     * @return true if the collection is modified by this call, false otherwise.
    822     */
    823    public static <T> boolean filterInverse(final Iterable<T> collection, final Predicate<? super T> predicate) {
    824        return filter(collection, predicate == null ? null : PredicateUtils.notPredicate(predicate));
    825    }
    826
    827    /**
    828     * Finds the first element in the given collection which matches the given predicate.
    829     * <p>
    830     * If the input collection or predicate is null, or no element of the collection matches the predicate, null is returned.
    831     * </p>
    832     *
    833     * @param <T>        the type of object the {@link Iterable} contains.
    834     * @param collection The collection to search, may be null.
    835     * @param predicate  The predicate to use, may be null.
    836     * @return The first element of the collection which matches the predicate or null if none could be found.
    837     * @deprecated Since 4.1, use {@link IterableUtils#find(Iterable, Predicate)} instead.
    838     */
    839    @Deprecated
    840    public static <T> T find(final Iterable<T> collection, final Predicate<? super T> predicate) {
    841        return predicate != null ? IterableUtils.find(collection, predicate) : null;
    842    }
    843
    844    /**
    845     * Executes the given closure on each but the last element in the collection.
    846     * <p>
    847     * If the input collection or closure is null, there is no change made.
    848     * </p>
    849     *
    850     * @param <T>        the type of object the {@link Iterable} contains.
    851     * @param <C>        the closure type.
    852     * @param collection The collection to get the input from, may be null.
    853     * @param closure    The closure to perform, may be null.
    854     * @return The last element in the collection, or null if either collection or closure is null.
    855     * @since 4.0
    856     * @deprecated Since 4.1, use {@link IterableUtils#forEachButLast(Iterable, Closure)} instead.
    857     */
    858    @Deprecated
    859    public static <T, C extends Closure<? super T>> T forAllButLastDo(final Iterable<T> collection, final C closure) {
    860        return closure != null ? IterableUtils.forEachButLast(collection, closure) : null;
    861    }
    862
    863    /**
    864     * Executes the given closure on each but the last element in the collection.
    865     * <p>
    866     * If the input collection or closure is null, there is no change made.
    867     * </p>
    868     *
    869     * @param <T>      the type of object the {@link Collection} contains.
    870     * @param <C>      the closure type.
    871     * @param iterator The iterator to get the input from, may be null.
    872     * @param closure  The closure to perform, may be null.
    873     * @return The last element in the collection, or null if either iterator or closure is null.
    874     * @since 4.0
    875     * @deprecated Since 4.1, use {@link IteratorUtils#forEachButLast(Iterator, Closure)} instead.
    876     */
    877    @Deprecated
    878    public static <T, C extends Closure<? super T>> T forAllButLastDo(final Iterator<T> iterator, final C closure) {
    879        return closure != null ? IteratorUtils.forEachButLast(iterator, closure) : null;
    880    }
    881
    882    /**
    883     * Executes the given closure on each element in the collection.
    884     * <p>
    885     * If the input collection or closure is null, there is no change made.
    886     * </p>
    887     *
    888     * @param <T>        the type of object the {@link Iterable} contains.
    889     * @param <C>        the closure type.
    890     * @param collection The collection to get the input from, may be null.
    891     * @param closure    The closure to perform, may be null.
    892     * @return closure
    893     * @deprecated Since 4.1, use {@link IterableUtils#forEach(Iterable, Closure)} instead.
    894     */
    895    @Deprecated
    896    public static <T, C extends Closure<? super T>> C forAllDo(final Iterable<T> collection, final C closure) {
    897        if (closure != null) {
    898            IterableUtils.forEach(collection, closure);
    899        }
    900        return closure;
    901    }
    902
    903    /**
    904     * Executes the given closure on each element in the collection.
    905     * <p>
    906     * If the input collection or closure is null, there is no change made.
    907     * </p>
    908     *
    909     * @param <T>      the type of object the {@link Iterator} contains.
    910     * @param <C>      the closure type.
    911     * @param iterator The iterator to get the input from, may be null.
    912     * @param closure  The closure to perform, may be null.
    913     * @return closure
    914     * @since 4.0
    915     * @deprecated Since 4.1, use {@link IteratorUtils#forEach(Iterator, Closure)} instead.
    916     */
    917    @Deprecated
    918    public static <T, C extends Closure<? super T>> C forAllDo(final Iterator<T> iterator, final C closure) {
    919        if (closure != null) {
    920            IteratorUtils.forEach(iterator, closure);
    921        }
    922        return closure;
    923    }
    924
    925    /**
    926     * Gets the {@code index}-th value in the {@code iterable}'s {@link Iterator}, throwing {@code IndexOutOfBoundsException} if there is no such element.
    927     * <p>
    928     * If the {@link Iterable} is a {@link List}, then it will use {@link List#get(int)}.
    929     * </p>
    930     *
    931     * @param iterable The {@link Iterable} to get a value from.
    932     * @param index    The index to get.
    933     * @param <T>      The type of object in the {@link Iterable}.
    934     * @return The object at the specified index.
    935     * @throws IndexOutOfBoundsException if the index is invalid.
    936     * @throws NullPointerException      if iterable is null.
    937     * @deprecated Since 4.1, use {@code IterableUtils.get(Iterable, int)} instead.
    938     */
    939    @Deprecated
    940    public static <T> T get(final Iterable<T> iterable, final int index) {
    941        Objects.requireNonNull(iterable, "iterable");
    942        return IterableUtils.get(iterable, index);
    943    }
    944
    945    /**
    946     * Gets the {@code index}-th value in {@link Iterator}, throwing {@code IndexOutOfBoundsException} if there is no such element.
    947     * <p>
    948     * The Iterator is advanced to {@code index} (or to the end, if {@code index} exceeds the number of entries) as a side effect of this method.
    949     * </p>
    950     *
    951     * @param iterator The iterator to get a value from.
    952     * @param index    The index to get.
    953     * @param <T>      The type of object in the {@link Iterator}.
    954     * @return The object at the specified index.
    955     * @throws IndexOutOfBoundsException if the index is invalid.
    956     * @throws IllegalArgumentException  if the object type is invalid.
    957     * @throws NullPointerException      if iterator is null.
    958     * @deprecated Since 4.1, use {@code IteratorUtils.get(Iterator, int)} instead.
    959     */
    960    @Deprecated
    961    public static <T> T get(final Iterator<T> iterator, final int index) {
    962        Objects.requireNonNull(iterator, "iterator");
    963        return IteratorUtils.get(iterator, index);
    964    }
    965
    966    /**
    967     * Gets the {@code index}-th {@code Map.Entry} in the {@code map}'s {@code entrySet}, throwing {@code IndexOutOfBoundsException} if there is no such
    968     * element.
    969     *
    970     * @param <K>   the key type in the {@link Map}.
    971     * @param <V>   the value type in the {@link Map}.
    972     * @param map   The object to get a value from.
    973     * @param index The index to get.
    974     * @return The object at the specified index.
    975     * @throws IndexOutOfBoundsException if the index is invalid.
    976     * @throws NullPointerException      if map is null.
    977     */
    978    public static <K, V> Map.Entry<K, V> get(final Map<K, V> map, final int index) {
    979        Objects.requireNonNull(map, "map");
    980        checkIndexBounds(index);
    981        return get(map.entrySet(), index);
    982    }
    983
    984    /**
    985     * Gets the {@code index}-th value in {@code object}, throwing {@code IndexOutOfBoundsException} if there is no such element or
    986     * {@code IllegalArgumentException} if {@code object} is not an instance of one of the supported types.
    987     * <p>
    988     * The supported types, and associated semantics are:
    989     * </p>
    990     * <ul>
    991     * <li>Map -- the value returned is the {@code Map.Entry} in position {@code index} in the map's {@code entrySet} iterator, if there is such an entry.</li>
    992     * <li>List -- this method is equivalent to the list's get method.</li>
    993     * <li>Array -- the {@code index}-th array entry is returned, if there is such an entry; otherwise an {@code IndexOutOfBoundsException} is thrown.</li>
    994     * <li>Collection -- the value returned is the {@code index}-th object returned by the collection's default iterator, if there is such an element.</li>
    995     * <li>Iterator or Enumeration -- the value returned is the {@code index}-th object in the Iterator/Enumeration, if there is such an element. The
    996     * Iterator/Enumeration is advanced to {@code index} (or to the end, if {@code index} exceeds the number of entries) as a side effect of this method.</li>
    997     * </ul>
    998     *
    999     * @param object The object to get a value from.
    1000     * @param index  The index to get.
    1001     * @return The object at the specified index.
    1002     * @throws IndexOutOfBoundsException if the index is invalid.
    1003     * @throws IllegalArgumentException  if the object type is invalid.
    1004     */
    1005    public static Object get(final Object object, final int index) {
    1006        final int i = index;
    1007        if (i < 0) {
    1008            throw new IndexOutOfBoundsException("Index cannot be negative: " + i);
    1009        }
    1010        if (object instanceof Map<?, ?>) {
    1011            final Map<?, ?> map = (Map<?, ?>) object;
    1012            final Iterator<?> iterator = map.entrySet().iterator();
    1013            return IteratorUtils.get(iterator, i);
    1014        }
    1015        if (object instanceof Object[]) {
    1016            return ((Object[]) object)[i];
    1017        }
    1018        if (object instanceof Iterator<?>) {
    1019            final Iterator<?> it = (Iterator<?>) object;
    1020            return IteratorUtils.get(it, i);
    1021        }
    1022        if (object instanceof Iterable<?>) {
    1023            final Iterable<?> iterable = (Iterable<?>) object;
    1024            return IterableUtils.get(iterable, i);
    1025        }
    1026        if (object instanceof Enumeration<?>) {
    1027            final Enumeration<?> it = (Enumeration<?>) object;
    1028            return EnumerationUtils.get(it, i);
    1029        }
    1030        if (object == null) {
    1031            throw new IllegalArgumentException("Unsupported object type: null");
    1032        }
    1033        try {
    1034            return Array.get(object, i);
    1035        } catch (final IllegalArgumentException ex) {
    1036            throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
    1037        }
    1038    }
    1039
    1040    /**
    1041     * Gets a {@link Map} mapping each unique element in the given {@link Collection} to an {@link Integer} representing the number of occurrences of that
    1042     * element in the {@link Collection}.
    1043     * <p>
    1044     * Only those elements present in the collection will appear as keys in the map.
    1045     * </p>
    1046     *
    1047     * @param <O>  the type of object in the returned {@link Map}. This is a super type of &lt;I&gt;.
    1048     * @param coll The collection to get the cardinality map for, must not be null.
    1049     * @return The populated cardinality map.
    1050     * @throws NullPointerException if coll is null.
    1051     */
    1052    public static <O> Map<O, Integer> getCardinalityMap(final Iterable<? extends O> coll) {
    1053        Objects.requireNonNull(coll, "coll");
    1054        final Map<O, Integer> count = new HashMap<>();
    1055        for (final O obj : coll) {
    1056            final Integer c = count.get(obj);
    1057            if (c == null) {
    1058                count.put(obj, Integer.valueOf(1));
    1059            } else {
    1060                count.put(obj, Integer.valueOf(c.intValue() + 1));
    1061            }
    1062        }
    1063        return count;
    1064    }
    1065
    1066    /**
    1067     * Returns the hash code of the input collection using the hash method of an equator.
    1068     * <p>
    1069     * Returns 0 if the input collection is {@code null}.
    1070     * </p>
    1071     *
    1072     * @param <E>        the element type.
    1073     * @param collection The input collection.
    1074     * @param equator    The equator used for generate hashCode.
    1075     * @return The hash code of the input collection using the hash method of an equator.
    1076     * @throws NullPointerException if the equator is {@code null}.
    1077     * @since 4.5.0-M1
    1078     */
    1079    public static <E> int hashCode(final Collection<? extends E> collection, final Equator<? super E> equator) {
    1080        Objects.requireNonNull(equator, "equator");
    1081        if (collection == null) {
    1082            return 0;
    1083        }
    1084        int hashCode = 1;
    1085        for (final E e : collection) {
    1086            hashCode = 31 * hashCode + equator.hash(e);
    1087        }
    1088        return hashCode;
    1089    }
    1090
    1091    /**
    1092     * Returns a {@link Collection} containing the intersection of the given {@link Iterable}s.
    1093     * <p>
    1094     * The cardinality of each element in the returned {@link Collection} will be equal to the minimum of the cardinality of that element in the two given
    1095     * {@link Iterable}s.
    1096     * </p>
    1097     *
    1098     * @param a   The first collection, must not be null.
    1099     * @param b   The second collection, must not be null.
    1100     * @param <O> The generic type that is able to represent the types contained in both input collections.
    1101     * @return The intersection of the two collections.
    1102     * @throws NullPointerException if either collection is null.
    1103     * @see Collection#retainAll
    1104     * @see #containsAny
    1105     */
    1106    public static <O> Collection<O> intersection(final Iterable<? extends O> a, final Iterable<? extends O> b) {
    1107        Objects.requireNonNull(a, "a");
    1108        Objects.requireNonNull(b, "b");
    1109        final SetOperationCardinalityHelper<O> helper = new SetOperationCardinalityHelper<>(a, b);
    1110        for (final O obj : helper) {
    1111            helper.setCardinality(obj, helper.min(obj));
    1112        }
    1113        return helper.list();
    1114    }
    1115
    1116    /**
    1117     * Null-safe check if the specified collection is empty.
    1118     * <p>
    1119     * Null returns true.
    1120     * </p>
    1121     *
    1122     * @param coll The collection to check, may be null.
    1123     * @return true if empty or null
    1124     * @since 3.2
    1125     */
    1126    public static boolean isEmpty(final Collection<?> coll) {
    1127        return coll == null || coll.isEmpty();
    1128    }
    1129
    1130    /**
    1131     * Returns {@code true} iff the given {@link Collection}s contain exactly the same elements with exactly the same cardinalities.
    1132     * <p>
    1133     * That is, iff the cardinality of <em>e</em> in <em>a</em> is equal to the cardinality of <em>e</em> in <em>b</em>, for each element <em>e</em> in
    1134     * <em>a</em> or <em>b</em>.
    1135     * </p>
    1136     *
    1137     * @param a The first collection, must not be null.
    1138     * @param b The second collection, must not be null.
    1139     * @return {@code true} iff the collections contain the same elements with the same cardinalities.
    1140     * @throws NullPointerException if either collection is null.
    1141     */
    1142    public static boolean isEqualCollection(final Collection<?> a, final Collection<?> b) {
    1143        return CardinalityHelper.equals(a, b);
    1144    }
    1145
    1146    /**
    1147     * Returns {@code true} iff the given {@link Collection}s contain exactly the same elements with exactly the same cardinalities.
    1148     * <p>
    1149     * That is, iff the cardinality of <em>e</em> in <em>a</em> is equal to the cardinality of <em>e</em> in <em>b</em>, for each element <em>e</em> in
    1150     * <em>a</em> or <em>b</em>.
    1151     * </p>
    1152     * <p>
    1153     * <strong>Note:</strong> from version 4.1 onwards this method requires the input collections and equator to be of compatible type (using bounded
    1154     * wildcards). Providing incompatible arguments (for example by casting to their rawtypes) will result in a {@code ClassCastException} thrown at runtime.
    1155     * </p>
    1156     *
    1157     * @param <E>     the element type.
    1158     * @param a       The first collection, must not be null.
    1159     * @param b       The second collection, must not be null.
    1160     * @param equator The Equator used for testing equality.
    1161     * @return {@code true} iff the collections contain the same elements with the same cardinalities.
    1162     * @throws NullPointerException if either collection or equator is null.
    1163     * @since 4.0
    1164     */
    1165    public static <E> boolean isEqualCollection(final Collection<? extends E> a, final Collection<? extends E> b, final Equator<? super E> equator) {
    1166        Objects.requireNonNull(a, "a");
    1167        Objects.requireNonNull(b, "b");
    1168        Objects.requireNonNull(equator, "equator");
    1169        if (a.size() != b.size()) {
    1170            return false;
    1171        }
    1172        @SuppressWarnings({ "unchecked", "rawtypes" })
    1173        final Transformer<E, ?> transformer = input -> new EquatorWrapper(equator, input);
    1174        return isEqualCollection(collect(a, transformer), collect(b, transformer));
    1175    }
    1176
    1177    /**
    1178     * Returns true if no more elements can be added to the Collection.
    1179     * <p>
    1180     * This method uses the {@link BoundedCollection} interface to determine the full status. If the collection does not implement this interface then false is
    1181     * returned.
    1182     * </p>
    1183     * <p>
    1184     * The collection does not have to implement this interface directly. If the collection has been decorated using the decorators subpackage then these will
    1185     * be removed to access the BoundedCollection.
    1186     * </p>
    1187     *
    1188     * @param collection The collection to check.
    1189     * @return true if the BoundedCollection is full.
    1190     * @throws NullPointerException if the collection is null.
    1191     */
    1192    public static boolean isFull(final Collection<? extends Object> collection) {
    1193        Objects.requireNonNull(collection, "collection");
    1194        if (collection instanceof BoundedCollection) {
    1195            return ((BoundedCollection<?>) collection).isFull();
    1196        }
    1197        try {
    1198            final BoundedCollection<?> bcoll = UnmodifiableBoundedCollection.unmodifiableBoundedCollection(collection);
    1199            return bcoll.isFull();
    1200        } catch (final IllegalArgumentException ex) {
    1201            return false;
    1202        }
    1203    }
    1204
    1205    /**
    1206     * Null-safe check if the specified collection is not empty.
    1207     * <p>
    1208     * Null returns false.
    1209     * </p>
    1210     *
    1211     * @param coll The collection to check, may be null.
    1212     * @return true if non-null and non-empty.
    1213     * @since 3.2
    1214     */
    1215    public static boolean isNotEmpty(final Collection<?> coll) {
    1216        return !isEmpty(coll);
    1217    }
    1218
    1219    /**
    1220     * Returns {@code true} iff <em>a</em> is a <em>proper</em> sub-collection of <em>b</em>, that is, iff the cardinality of <em>e</em> in <em>a</em> is less
    1221     * than or equal to the cardinality of <em>e</em> in <em>b</em>, for each element <em>e</em> in <em>a</em>, and there is at least one element <em>f</em>
    1222     * such that the cardinality of <em>f</em> in <em>b</em> is strictly greater than the cardinality of <em>f</em> in <em>a</em>.
    1223     * <p>
    1224     * The implementation assumes
    1225     * </p>
    1226     * <ul>
    1227     * <li>{@code a.size()} and {@code b.size()} represent the total cardinality of <em>a</em> and <em>b</em>, resp.</li>
    1228     * <li>{@code a.size() &lt; Integer.MAXVALUE}</li>
    1229     * </ul>
    1230     *
    1231     * @param a The first (sub?) collection, must not be null.
    1232     * @param b The second (super?) collection, must not be null.
    1233     * @return {@code true} iff <em>a</em> is a <em>proper</em> sub-collection of <em>b</em>.
    1234     * @throws NullPointerException if either collection is null.
    1235     * @see #isSubCollection
    1236     * @see Collection#containsAll
    1237     */
    1238    public static boolean isProperSubCollection(final Collection<?> a, final Collection<?> b) {
    1239        Objects.requireNonNull(a, "a");
    1240        Objects.requireNonNull(b, "b");
    1241        return a.size() < b.size() && isSubCollection(a, b);
    1242    }
    1243
    1244    /**
    1245     * Returns {@code true} iff <em>a</em> is a sub-collection of <em>b</em>, that is, iff the cardinality of <em>e</em> in <em>a</em> is less than or equal to
    1246     * the cardinality of <em>e</em> in <em>b</em>, for each element <em>e</em> in <em>a</em>.
    1247     *
    1248     * @param a The first (sub?) collection, must not be null.
    1249     * @param b The second (super?) collection, must not be null.
    1250     * @return {@code true} iff <em>a</em> is a sub-collection of <em>b</em>.
    1251     * @throws NullPointerException if either collection is null.
    1252     * @see #isProperSubCollection
    1253     * @see Collection#containsAll
    1254     */
    1255    public static boolean isSubCollection(final Collection<?> a, final Collection<?> b) {
    1256        Objects.requireNonNull(a, "a");
    1257        Objects.requireNonNull(b, "b");
    1258        final CardinalityHelper<Object> helper = new CardinalityHelper<>(a, b);
    1259        for (final Object obj : a) {
    1260            if (helper.freqA(obj) > helper.freqB(obj)) {
    1261                return false;
    1262            }
    1263        }
    1264        return true;
    1265    }
    1266
    1267    /**
    1268     * Answers true if a predicate is true for every element of a collection.
    1269     * <p>
    1270     * A {@code null} predicate returns false.
    1271     * </p>
    1272     * <p>
    1273     * A {@code null} or empty collection returns true.
    1274     * </p>
    1275     *
    1276     * @param <C>       the type of object the {@link Iterable} contains.
    1277     * @param input     The {@link Iterable} to get the input from, may be null.
    1278     * @param predicate The predicate to use, may be null.
    1279     * @return true if every element of the collection matches the predicate or if the collection is empty, false otherwise.
    1280     * @since 4.0
    1281     * @deprecated Since 4.1, use {@link IterableUtils#matchesAll(Iterable, Predicate)} instead
    1282     */
    1283    @Deprecated
    1284    public static <C> boolean matchesAll(final Iterable<C> input, final Predicate<? super C> predicate) {
    1285        return predicate != null && IterableUtils.matchesAll(input, predicate);
    1286    }
    1287
    1288    /**
    1289     * Gets the maximum number of elements that the Collection can contain.
    1290     * <p>
    1291     * This method uses the {@link BoundedCollection} interface to determine the maximum size. If the collection does not implement this interface then -1 is
    1292     * returned.
    1293     * </p>
    1294     * <p>
    1295     * The collection does not have to implement this interface directly. If the collection has been decorated using the decorators subpackage then these will
    1296     * be removed to access the BoundedCollection.
    1297     * </p>
    1298     *
    1299     * @param collection The collection to check.
    1300     * @return The maximum size of the BoundedCollection, -1 if no maximum size.
    1301     * @throws NullPointerException if the collection is null.
    1302     */
    1303    public static int maxSize(final Collection<? extends Object> collection) {
    1304        Objects.requireNonNull(collection, "collection");
    1305        if (collection instanceof BoundedCollection) {
    1306            return ((BoundedCollection<?>) collection).maxSize();
    1307        }
    1308        try {
    1309            final BoundedCollection<?> bcoll = UnmodifiableBoundedCollection.unmodifiableBoundedCollection(collection);
    1310            return bcoll.maxSize();
    1311        } catch (final IllegalArgumentException ex) {
    1312            return -1;
    1313        }
    1314    }
    1315
    1316    /**
    1317     * Returns a {@link Collection} of all the permutations of the input collection.
    1318     * <p>
    1319     * NOTE: the number of permutations of a given collection is equal to n!, where n is the size of the collection. Thus, the resulting collection will become
    1320     * <strong>very</strong> large for collections &gt; 10 (for example 10! = 3628800, 15! = 1307674368000).
    1321     * </p>
    1322     * <p>
    1323     * For larger collections it is advised to use a {@link PermutationIterator} to iterate over all permutations.
    1324     * </p>
    1325     *
    1326     * @param <E>        the element type.
    1327     * @param collection The collection to create permutations for, must not be null.
    1328     * @return An unordered collection of all permutations of the input collection.
    1329     * @throws NullPointerException if collection is null.
    1330     * @see PermutationIterator
    1331     * @since 4.0
    1332     */
    1333    public static <E> Collection<List<E>> permutations(final Collection<E> collection) {
    1334        Objects.requireNonNull(collection, "collection");
    1335        final PermutationIterator<E> it = new PermutationIterator<>(collection);
    1336        final Collection<List<E>> result = new ArrayList<>();
    1337        while (it.hasNext()) {
    1338            result.add(it.next());
    1339        }
    1340        return result;
    1341    }
    1342
    1343    /**
    1344     * Returns a predicated (validating) collection backed by the given collection.
    1345     * <p>
    1346     * Only objects that pass the test in the given predicate can be added to the collection. Trying to add an invalid object results in an
    1347     * IllegalArgumentException. It is important not to use the original collection after invoking this method, as it is a backdoor for adding invalid objects.
    1348     * </p>
    1349     *
    1350     * @param <C>        The type of objects in the Collection.
    1351     * @param collection The collection to predicate, must not be null.
    1352     * @param predicate  The predicate for the collection, must not be null.
    1353     * @return A predicated collection backed by the given collection.
    1354     * @throws NullPointerException if the collection or predicate is null.
    1355     */
    1356    public static <C> Collection<C> predicatedCollection(final Collection<C> collection, final Predicate<? super C> predicate) {
    1357        Objects.requireNonNull(collection, "collection");
    1358        Objects.requireNonNull(predicate, "predicate");
    1359        return PredicatedCollection.predicatedCollection(collection, predicate);
    1360    }
    1361
    1362    /**
    1363     * Removes the elements in {@code remove} from {@code collection}. That is, this method returns a collection containing all the elements in {@code c} that
    1364     * are not in {@code remove}. The cardinality of an element {@code e} in the returned collection is the same as the cardinality of {@code e} in
    1365     * {@code collection} unless {@code remove} contains {@code e}, in which case the cardinality is zero. This method is useful if you do not wish to modify
    1366     * the collection {@code c} and thus cannot call {@code collection.removeAll(remove);}.
    1367     * <p>
    1368     * This implementation iterates over {@code collection}, checking each element in turn to see if it's contained in {@code remove}. If it's not contained,
    1369     * it's added to the returned list. As a consequence, it is advised to use a collection type for {@code remove} that provides a fast (for example O(1))
    1370     * implementation of {@link Collection#contains(Object)}.
    1371     * </p>
    1372     *
    1373     * @param <E>        the type of object the {@link Collection} contains.
    1374     * @param collection The collection from which items are removed (in the returned collection).
    1375     * @param remove     The items to be removed from the returned {@code collection}.
    1376     * @return A {@code Collection} containing all the elements of {@code collection} except any elements that also occur in {@code remove}.
    1377     * @throws NullPointerException if either parameter is null.
    1378     * @since 4.0 (method existed in 3.2 but was completely broken).
    1379     */
    1380    public static <E> Collection<E> removeAll(final Collection<E> collection, final Collection<?> remove) {
    1381        return ListUtils.removeAll(collection, remove);
    1382    }
    1383
    1384    /**
    1385     * Removes all elements in {@code remove} from {@code collection}. That is, this method returns a collection containing all the elements in
    1386     * {@code collection} that are not in {@code remove}. The cardinality of an element {@code e} in the returned collection is the same as the cardinality of
    1387     * {@code e} in {@code collection} unless {@code remove} contains {@code e}, in which case the cardinality is zero. This method is useful if you do not wish
    1388     * to modify the collection {@code c} and thus cannot call {@code collection.removeAll(remove)}.
    1389     * <p>
    1390     * Moreover this method uses an {@link Equator} instead of {@link Object#equals(Object)} to determine the equality of the elements in {@code collection} and
    1391     * {@code remove}. Hence this method is useful in cases where the equals behavior of an object needs to be modified without changing the object itself.
    1392     * </p>
    1393     *
    1394     * @param <E>        The type of object the {@link Collection} contains.
    1395     * @param collection The collection from which items are removed (in the returned collection).
    1396     * @param remove     The items to be removed from the returned collection.
    1397     * @param equator    The Equator used for testing equality.
    1398     * @return A {@code Collection} containing all the elements of {@code collection} except any element that if equal according to the {@code equator}
    1399     * @throws NullPointerException if any of the parameters is null.
    1400     * @since 4.1
    1401     */
    1402    public static <E> Collection<E> removeAll(final Iterable<E> collection, final Iterable<? extends E> remove, final Equator<? super E> equator) {
    1403        Objects.requireNonNull(collection, "collection");
    1404        Objects.requireNonNull(remove, "remove");
    1405        Objects.requireNonNull(equator, "equator");
    1406        final Transformer<E, EquatorWrapper<E>> transformer = input -> new EquatorWrapper<>(equator, input);
    1407        final Set<EquatorWrapper<E>> removeSet = collect(remove, transformer, new HashSet<>());
    1408        final List<E> list = new ArrayList<>();
    1409        for (final E element : collection) {
    1410            if (!removeSet.contains(new EquatorWrapper<>(equator, element))) {
    1411                list.add(element);
    1412            }
    1413        }
    1414        return list;
    1415    }
    1416
    1417    /**
    1418     * Removes the specified number of elements from the start index in the collection and returns them. This method modifies the input collections.
    1419     *
    1420     * @param <E>        the type of object the {@link Collection} contains.
    1421     * @param input      The collection will be operated, can't be null.
    1422     * @param startIndex The start index (inclusive) to remove element, can't be less than 0.
    1423     * @param count      The specified number to remove, can't be less than 1.
    1424     * @return collection of elements that removed from the input collection.
    1425     * @throws NullPointerException      if input is null
    1426     * @throws IndexOutOfBoundsException if startIndex is less than 0, count is less than 0, or the sum of startIndex and count is greater than the collection size.
    1427     * @since 4.5.0-M1
    1428     */
    1429    public static <E> Collection<E> removeCount(final Collection<E> input, int startIndex, int count) {
    1430        Objects.requireNonNull(input, "input");
    1431        if (startIndex < 0) {
    1432            throw new IndexOutOfBoundsException("The start index can't be less than 0.");
    1433        }
    1434        if (count < 0) {
    1435            throw new IndexOutOfBoundsException("The count can't be less than 0.");
    1436        }
    1437        if (input.size() < startIndex + count) {
    1438            throw new IndexOutOfBoundsException("The sum of start index and count can't be greater than the size of collection.");
    1439        }
    1440        final Collection<E> result = new ArrayList<>(count);
    1441        final Iterator<E> iterator = input.iterator();
    1442        while (count > 0) {
    1443            if (startIndex > 0) {
    1444                startIndex -= 1;
    1445                iterator.next();
    1446                continue;
    1447            }
    1448            count -= 1;
    1449            result.add(iterator.next());
    1450            iterator.remove();
    1451        }
    1452        return result;
    1453    }
    1454
    1455    /**
    1456     * Removes elements whose index are between startIndex, inclusive and endIndex, exclusive in the collection and returns them. This method modifies the input
    1457     * collections.
    1458     *
    1459     * @param <E>        the type of object the {@link Collection} contains.
    1460     * @param input      The collection will be operated, must not be null.
    1461     * @param startIndex The start index (inclusive) to remove element, must not be less than 0.
    1462     * @param endIndex   The end index (exclusive) to remove, must not be less than startIndex.
    1463     * @return collection of elements that removed from the input collection.
    1464     * @throws NullPointerException      if input is null.
    1465     * @throws IllegalArgumentException  if endIndex is less than startIndex.
    1466     * @throws IndexOutOfBoundsException if endIndex is greater than the size of the collection, or startIndex is less than 0.
    1467     * @since 4.5.0-M1
    1468     */
    1469    public static <E> Collection<E> removeRange(final Collection<E> input, final int startIndex, final int endIndex) {
    1470        Objects.requireNonNull(input, "input");
    1471        if (endIndex < startIndex) {
    1472            throw new IllegalArgumentException("The end index can't be less than the start index.");
    1473        }
    1474        if (input.size() < endIndex) {
    1475            throw new IndexOutOfBoundsException("The end index can't be greater than the size of collection.");
    1476        }
    1477        return removeCount(input, startIndex, endIndex - startIndex);
    1478    }
    1479
    1480    /**
    1481     * Returns a collection containing all the elements in {@code collection} that are also in {@code retain}. The cardinality of an element {@code e} in the
    1482     * returned collection is the same as the cardinality of {@code e} in {@code collection} unless {@code retain} does not contain {@code e}, in which case the
    1483     * cardinality is zero. This method is useful if you do not wish to modify the collection {@code c} and thus cannot call {@code c.retainAll(retain);}.
    1484     * <p>
    1485     * This implementation iterates over {@code collection}, checking each element in turn to see if it's contained in {@code retain}. If it's contained, it's
    1486     * added to the returned list. As a consequence, it is advised to use a collection type for {@code retain} that provides a fast (for example O(1))
    1487     * implementation of {@link Collection#contains(Object)}.
    1488     * </p>
    1489     *
    1490     * @param <C>        the type of object the {@link Collection} contains.
    1491     * @param collection The collection whose contents are the target of the #retailAll operation.
    1492     * @param retain     The collection containing the elements to be retained in the returned collection.
    1493     * @return A {@code Collection} containing all the elements of {@code collection} that occur at least once in {@code retain}.
    1494     * @throws NullPointerException if either parameter is null.
    1495     * @since 3.2
    1496     */
    1497    public static <C> Collection<C> retainAll(final Collection<C> collection, final Collection<?> retain) {
    1498        Objects.requireNonNull(collection, "collection");
    1499        Objects.requireNonNull(retain, "retain");
    1500        return ListUtils.retainAll(collection, retain);
    1501    }
    1502
    1503    /**
    1504     * Returns a collection containing all the elements in {@code collection} that are also in {@code retain}. The cardinality of an element {@code e} in the
    1505     * returned collection is the same as the cardinality of {@code e} in {@code collection} unless {@code retain} does not contain {@code e}, in which case the
    1506     * cardinality is zero. This method is useful if you do not wish to modify the collection {@code c} and thus cannot call {@code c.retainAll(retain);}.
    1507     * <p>
    1508     * Moreover this method uses an {@link Equator} instead of {@link Object#equals(Object)} to determine the equality of the elements in {@code collection} and
    1509     * {@code retain}. Hence this method is useful in cases where the equals behavior of an object needs to be modified without changing the object itself.
    1510     * </p>
    1511     *
    1512     * @param <E>        The type of object the {@link Collection} contains.
    1513     * @param collection The collection whose contents are the target of the {@code retainAll} operation.
    1514     * @param retain     The collection containing the elements to be retained in the returned collection.
    1515     * @param equator    The Equator used for testing equality.
    1516     * @return A {@code Collection} containing all the elements of {@code collection} that occur at least once in {@code retain} according to the
    1517     *         {@code equator}.
    1518     * @throws NullPointerException if any of the parameters is null.
    1519     * @since 4.1
    1520     */
    1521    public static <E> Collection<E> retainAll(final Iterable<E> collection, final Iterable<? extends E> retain, final Equator<? super E> equator) {
    1522        Objects.requireNonNull(collection, "collection");
    1523        Objects.requireNonNull(retain, "retain");
    1524        Objects.requireNonNull(equator, "equator");
    1525        final Transformer<E, EquatorWrapper<E>> transformer = input -> new EquatorWrapper<>(equator, input);
    1526        final Set<EquatorWrapper<E>> retainSet = collect(retain, transformer, new HashSet<>());
    1527        final List<E> list = new ArrayList<>();
    1528        for (final E element : collection) {
    1529            if (retainSet.contains(new EquatorWrapper<>(equator, element))) {
    1530                list.add(element);
    1531            }
    1532        }
    1533        return list;
    1534    }
    1535
    1536    /**
    1537     * Reverses the order of the given array.
    1538     *
    1539     * @param array The array to reverse.
    1540     * @throws NullPointerException if array is null.
    1541     */
    1542    public static void reverseArray(final Object[] array) {
    1543        Objects.requireNonNull(array, "array");
    1544        int i = 0;
    1545        int j = array.length - 1;
    1546        Object tmp;
    1547        while (j > i) {
    1548            tmp = array[j];
    1549            array[j] = array[i];
    1550            array[i] = tmp;
    1551            j--;
    1552            i++;
    1553        }
    1554    }
    1555
    1556    /**
    1557     * Selects all elements from input collection which match the given predicate into an output collection.
    1558     * <p>
    1559     * A {@code null} predicate matches no elements.
    1560     * </p>
    1561     *
    1562     * @param <O>             the type of object the {@link Iterable} contains.
    1563     * @param inputCollection The collection to get the input from, may not be null.
    1564     * @param predicate       The predicate to use, may be null.
    1565     * @return The elements matching the predicate (new list).
    1566     */
    1567    public static <O> Collection<O> select(final Iterable<? extends O> inputCollection, final Predicate<? super O> predicate) {
    1568        int size = 0;
    1569        if (inputCollection != null) {
    1570            size = inputCollection instanceof Collection<?> ? ((Collection<?>) inputCollection).size() : 0;
    1571        }
    1572        final Collection<O> answer = size == 0 ? new ArrayList<>() : new ArrayList<>(size);
    1573        return select(inputCollection, predicate, answer);
    1574    }
    1575
    1576    /**
    1577     * Selects all elements from input collection which match the given predicate and adds them to outputCollection.
    1578     * <p>
    1579     * If the input collection or predicate is null, there is no change to the output collection.
    1580     * </p>
    1581     *
    1582     * @param <O>              the type of object the {@link Iterable} contains.
    1583     * @param <R>              the type of the output {@link Collection}.
    1584     * @param inputCollection  The collection to get the input from, may be null.
    1585     * @param predicate        The predicate to use, may be null.
    1586     * @param outputCollection The collection to output into, may not be null if the inputCollection and predicate or not null.
    1587     * @return The outputCollection
    1588     */
    1589    public static <O, R extends Collection<? super O>> R select(final Iterable<? extends O> inputCollection, final Predicate<? super O> predicate,
    1590            final R outputCollection) {
    1591        if (inputCollection != null && predicate != null) {
    1592            for (final O item : inputCollection) {
    1593                if (predicate.test(item)) {
    1594                    outputCollection.add(item);
    1595                }
    1596            }
    1597        }
    1598        return outputCollection;
    1599    }
    1600
    1601    /**
    1602     * Selects all elements from inputCollection into an output and rejected collection, based on the evaluation of the given predicate.
    1603     * <p>
    1604     * Elements matching the predicate are added to the {@code outputCollection}, all other elements are added to the {@code rejectedCollection}.
    1605     * </p>
    1606     * <p>
    1607     * If the input predicate is {@code null}, no elements are added to {@code outputCollection} or {@code rejectedCollection}.
    1608     * </p>
    1609     * <p>
    1610     * Note: calling the method is equivalent to the following code snippet:
    1611     * </p>
    1612     *
    1613     * <pre>
    1614     * select(inputCollection, predicate, outputCollection);
    1615     * selectRejected(inputCollection, predicate, rejectedCollection);
    1616     * </pre>
    1617     *
    1618     * @param <O>                the type of object the {@link Iterable} contains.
    1619     * @param <R>                the type of the output {@link Collection}.
    1620     * @param inputCollection    The collection to get the input from, may be null.
    1621     * @param predicate          The predicate to use, may be null.
    1622     * @param outputCollection   The collection to output selected elements into, may not be null if the inputCollection and predicate are not null.
    1623     * @param rejectedCollection The collection to output rejected elements into, may not be null if the inputCollection or predicate are not null.
    1624     * @return The outputCollection
    1625     * @since 4.1
    1626     */
    1627    public static <O, R extends Collection<? super O>> R select(final Iterable<? extends O> inputCollection, final Predicate<? super O> predicate,
    1628            final R outputCollection, final R rejectedCollection) {
    1629        if (inputCollection != null && predicate != null) {
    1630            for (final O element : inputCollection) {
    1631                if (predicate.test(element)) {
    1632                    outputCollection.add(element);
    1633                } else {
    1634                    rejectedCollection.add(element);
    1635                }
    1636            }
    1637        }
    1638        return outputCollection;
    1639    }
    1640
    1641    /**
    1642     * Selects all elements from inputCollection which don't match the given predicate into an output collection.
    1643     * <p>
    1644     * If the input predicate is {@code null}, the result is an empty list.
    1645     * </p>
    1646     *
    1647     * @param <O>             the type of object the {@link Iterable} contains.
    1648     * @param inputCollection The collection to get the input from, may not be null.
    1649     * @param predicate       The predicate to use, may be null.
    1650     * @return The elements <strong>not</strong> matching the predicate (new list).
    1651     */
    1652    public static <O> Collection<O> selectRejected(final Iterable<? extends O> inputCollection, final Predicate<? super O> predicate) {
    1653        int size = 0;
    1654        if (inputCollection != null) {
    1655            size = inputCollection instanceof Collection<?> ? ((Collection<?>) inputCollection).size() : 0;
    1656        }
    1657        final Collection<O> answer = size == 0 ? new ArrayList<>() : new ArrayList<>(size);
    1658        return selectRejected(inputCollection, predicate, answer);
    1659    }
    1660
    1661    /**
    1662     * Selects all elements from inputCollection which don't match the given predicate and adds them to outputCollection.
    1663     * <p>
    1664     * If the input predicate is {@code null}, no elements are added to {@code outputCollection}.
    1665     * </p>
    1666     *
    1667     * @param <O>              the type of object the {@link Iterable} contains.
    1668     * @param <R>              the type of the output {@link Collection}.
    1669     * @param inputCollection  The collection to get the input from, may be null.
    1670     * @param predicate        The predicate to use, may be null.
    1671     * @param outputCollection The collection to output into, may not be null if the inputCollection and predicate or not null.
    1672     * @return outputCollection
    1673     */
    1674    public static <O, R extends Collection<? super O>> R selectRejected(final Iterable<? extends O> inputCollection, final Predicate<? super O> predicate,
    1675            final R outputCollection) {
    1676        if (inputCollection != null && predicate != null) {
    1677            for (final O item : inputCollection) {
    1678                if (!predicate.test(item)) {
    1679                    outputCollection.add(item);
    1680                }
    1681            }
    1682        }
    1683        return outputCollection;
    1684    }
    1685
    1686    /**
    1687     * Gets the size of the collection/iterator specified.
    1688     * <p>
    1689     * This method can handles objects as follows
    1690     * </p>
    1691     * <ul>
    1692     * <li>Collection - the collection size</li>
    1693     * <li>Map - the map size</li>
    1694     * <li>Array - the array size</li>
    1695     * <li>Iterator - the number of elements remaining in the iterator</li>
    1696     * <li>Enumeration - the number of elements remaining in the enumeration</li>
    1697     * </ul>
    1698     *
    1699     * @param object The object to get the size of, may be null.
    1700     * @return The size of the specified collection or 0 if the object was null.
    1701     * @throws IllegalArgumentException thrown if object is not recognized.
    1702     * @since 3.1
    1703     */
    1704    public static int size(final Object object) {
    1705        if (object == null) {
    1706            return 0;
    1707        }
    1708        int total = 0;
    1709        if (object instanceof Map<?, ?>) {
    1710            total = ((Map<?, ?>) object).size();
    1711        } else if (object instanceof Collection<?>) {
    1712            total = ((Collection<?>) object).size();
    1713        } else if (object instanceof Iterable<?>) {
    1714            total = IterableUtils.size((Iterable<?>) object);
    1715        } else if (object instanceof Object[]) {
    1716            total = ((Object[]) object).length;
    1717        } else if (object instanceof Iterator<?>) {
    1718            total = IteratorUtils.size((Iterator<?>) object);
    1719        } else if (object instanceof Enumeration<?>) {
    1720            final Enumeration<?> it = (Enumeration<?>) object;
    1721            while (it.hasMoreElements()) {
    1722                total++;
    1723                it.nextElement();
    1724            }
    1725        } else {
    1726            try {
    1727                total = Array.getLength(object);
    1728            } catch (final IllegalArgumentException ex) {
    1729                throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
    1730            }
    1731        }
    1732        return total;
    1733    }
    1734
    1735    /**
    1736     * Checks if the specified collection/array/iterator is empty.
    1737     * <p>
    1738     * This method can handles objects as follows
    1739     * </p>
    1740     * <ul>
    1741     * <li>Collection - via collection isEmpty</li>
    1742     * <li>Map - via map isEmpty</li>
    1743     * <li>Array - using array size</li>
    1744     * <li>Iterator - via hasNext</li>
    1745     * <li>Enumeration - via hasMoreElements</li>
    1746     * </ul>
    1747     * <p>
    1748     * Note: This method is named to avoid clashing with {@link #isEmpty(Collection)}.
    1749     * </p>
    1750     *
    1751     * @param object The object to get the size of, may be null.
    1752     * @return true if empty or null.
    1753     * @throws IllegalArgumentException thrown if object is not recognized.
    1754     * @since 3.2
    1755     */
    1756    public static boolean sizeIsEmpty(final Object object) {
    1757        if (object == null) {
    1758            return true;
    1759        }
    1760        if (object instanceof Collection<?>) {
    1761            return ((Collection<?>) object).isEmpty();
    1762        }
    1763        if (object instanceof Iterable<?>) {
    1764            return IterableUtils.isEmpty((Iterable<?>) object);
    1765        }
    1766        if (object instanceof Map<?, ?>) {
    1767            return ((Map<?, ?>) object).isEmpty();
    1768        }
    1769        if (object instanceof Object[]) {
    1770            return ((Object[]) object).length == 0;
    1771        }
    1772        if (object instanceof Iterator<?>) {
    1773            return !((Iterator<?>) object).hasNext();
    1774        }
    1775        if (object instanceof Enumeration<?>) {
    1776            return !((Enumeration<?>) object).hasMoreElements();
    1777        }
    1778        try {
    1779            return Array.getLength(object) == 0;
    1780        } catch (final IllegalArgumentException ex) {
    1781            throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
    1782        }
    1783    }
    1784
    1785    /**
    1786     * Returns a new {@link Collection} containing {@code <em>a</em> - <em>b</em>}. The cardinality of each element <em>e</em> in the returned
    1787     * {@link Collection} will be the cardinality of <em>e</em> in <em>a</em> minus the cardinality of <em>e</em> in <em>b</em>, or zero, whichever is greater.
    1788     *
    1789     * @param a   The collection to subtract from, must not be null.
    1790     * @param b   The collection to subtract, must not be null.
    1791     * @param <O> The generic type that is able to represent the types contained in both input collections.
    1792     * @return A new collection with the results.
    1793     * @throws NullPointerException if either collection is null.
    1794     * @see Collection#removeAll
    1795     */
    1796    public static <O> Collection<O> subtract(final Iterable<? extends O> a, final Iterable<? extends O> b) {
    1797        final Predicate<O> p = TruePredicate.truePredicate();
    1798        return subtract(a, b, p);
    1799    }
    1800
    1801    /**
    1802     * Returns a new {@link Collection} containing <em>a</em> minus a subset of <em>b</em>. Only the elements of <em>b</em> that satisfy the predicate
    1803     * condition, <em>p</em> are subtracted from <em>a</em>.
    1804     * <p>
    1805     * The cardinality of each element <em>e</em> in the returned {@link Collection} that satisfies the predicate condition will be the cardinality of
    1806     * <em>e</em> in <em>a</em> minus the cardinality of <em>e</em> in <em>b</em>, or zero, whichever is greater.
    1807     * </p>
    1808     * <p>
    1809     * The cardinality of each element <em>e</em> in the returned {@link Collection} that does <strong>not</strong> satisfy the predicate condition will be
    1810     * equal to the cardinality of <em>e</em> in <em>a</em>.
    1811     * </p>
    1812     *
    1813     * @param a   The collection to subtract from, must not be null.
    1814     * @param b   The collection to subtract, must not be null.
    1815     * @param p   The condition used to determine which elements of <em>b</em> are subtracted.
    1816     * @param <O> The generic type that is able to represent the types contained in both input collections.
    1817     * @return A new collection with the results.
    1818     * @throws NullPointerException if either collection or p is null.
    1819     * @since 4.0
    1820     * @see Collection#removeAll
    1821     */
    1822    public static <O> Collection<O> subtract(final Iterable<? extends O> a, final Iterable<? extends O> b, final Predicate<O> p) {
    1823        Objects.requireNonNull(a, "a");
    1824        Objects.requireNonNull(b, "b");
    1825        Objects.requireNonNull(p, "p");
    1826        final ArrayList<O> list = new ArrayList<>();
    1827        final HashMultiSet<O> multiSet = new HashMultiSet<>();
    1828        for (final O element : b) {
    1829            if (p.test(element)) {
    1830                multiSet.add(element);
    1831            }
    1832        }
    1833        for (final O element : a) {
    1834            if (multiSet.remove(element, 1) == 0) {
    1835                list.add(element);
    1836            }
    1837        }
    1838        return list;
    1839    }
    1840
    1841    /**
    1842     * Returns a synchronized collection backed by the given collection.
    1843     * <p>
    1844     * You must manually synchronize on the returned buffer's iterator to avoid non-deterministic behavior:
    1845     * </p>
    1846     *
    1847     * <pre>
    1848     * Collection c = CollectionUtils.synchronizedCollection(myCollection);
    1849     * synchronized (c) {
    1850     *     Iterator i = c.iterator();
    1851     *     while (i.hasNext()) {
    1852     *         process(i.next());
    1853     *     }
    1854     * }
    1855     * </pre>
    1856     * <p>
    1857     * This method uses the implementation in the decorators subpackage.
    1858     * </p>
    1859     *
    1860     * @param <C>        the type of object the {@link Collection} contains.
    1861     * @param collection The collection to synchronize, must not be null.
    1862     * @return A synchronized collection backed by the given collection.
    1863     * @throws NullPointerException if the collection is null.
    1864     * @deprecated Since 4.1, use {@link java.util.Collections#synchronizedCollection(Collection)} instead.
    1865     */
    1866    @Deprecated
    1867    public static <C> Collection<C> synchronizedCollection(final Collection<C> collection) {
    1868        Objects.requireNonNull(collection, "collection");
    1869        return SynchronizedCollection.synchronizedCollection(collection);
    1870    }
    1871
    1872    /**
    1873     * Transform the collection by applying a Transformer to each element.
    1874     * <p>
    1875     * If the input collection or transformer is null, there is no change made.
    1876     * </p>
    1877     * <p>
    1878     * This routine is best for Lists, for which set() is used to do the transformations "in place." For other Collections, clear() and addAll() are used to
    1879     * replace elements.
    1880     * </p>
    1881     * <p>
    1882     * If the input collection controls its input, such as a Set, and the Transformer creates duplicates (or are otherwise invalid), the collection may reduce
    1883     * in size due to calling this method.
    1884     * </p>
    1885     *
    1886     * @param <C>         the type of object the {@link Collection} contains.
    1887     * @param collection  The {@link Collection} to get the input from, may be null.
    1888     * @param transformer The transformer to perform, may be null.
    1889     */
    1890    public static <C> void transform(final Collection<C> collection, final Transformer<? super C, ? extends C> transformer) {
    1891        if (collection != null && transformer != null) {
    1892            if (collection instanceof List<?>) {
    1893                final List<C> list = (List<C>) collection;
    1894                for (final ListIterator<C> it = list.listIterator(); it.hasNext();) {
    1895                    it.set(transformer.apply(it.next()));
    1896                }
    1897            } else {
    1898                final Collection<C> resultCollection = collect(collection, transformer);
    1899                collection.clear();
    1900                collection.addAll(resultCollection);
    1901            }
    1902        }
    1903    }
    1904
    1905    /**
    1906     * Returns a transformed bag backed by the given collection.
    1907     * <p>
    1908     * Each object is passed through the transformer as it is added to the Collection. It is important not to use the original collection after invoking this
    1909     * method, as it is a backdoor for adding untransformed objects.
    1910     * </p>
    1911     * <p>
    1912     * Existing entries in the specified collection will not be transformed. If you want that behavior, see {@link TransformedCollection#transformedCollection}.
    1913     * </p>
    1914     *
    1915     * @param <E>         The type of object the {@link Collection} contains.
    1916     * @param collection  The collection to predicate, must not be null.
    1917     * @param transformer The transformer for the collection, must not be null.
    1918     * @return A transformed collection backed by the given collection.
    1919     * @throws NullPointerException if the collection or transformer is null.
    1920     */
    1921    public static <E> Collection<E> transformingCollection(final Collection<E> collection, final Transformer<? super E, ? extends E> transformer) {
    1922        Objects.requireNonNull(collection, "collection");
    1923        Objects.requireNonNull(transformer, "transformer");
    1924        return TransformedCollection.transformingCollection(collection, transformer);
    1925    }
    1926
    1927    /**
    1928     * Returns a {@link Collection} containing the union of the given {@link Iterable}s.
    1929     * <p>
    1930     * The cardinality of each element in the returned {@link Collection} will be equal to the maximum of the cardinality of that element in the two given
    1931     * {@link Iterable}s.
    1932     * </p>
    1933     *
    1934     * @param a   The first collection, must not be null.
    1935     * @param b   The second collection, must not be null.
    1936     * @param <O> The generic type that is able to represent the types contained in both input collections.
    1937     * @return The union of the two collections.
    1938     * @throws NullPointerException if either collection is null.
    1939     * @see Collection#addAll
    1940     */
    1941    public static <O> Collection<O> union(final Iterable<? extends O> a, final Iterable<? extends O> b) {
    1942        Objects.requireNonNull(a, "a");
    1943        Objects.requireNonNull(b, "b");
    1944        final SetOperationCardinalityHelper<O> helper = new SetOperationCardinalityHelper<>(a, b);
    1945        for (final O obj : helper) {
    1946            helper.setCardinality(obj, helper.max(obj));
    1947        }
    1948        return helper.list();
    1949    }
    1950
    1951    /**
    1952     * Returns an unmodifiable collection backed by the given collection.
    1953     * <p>
    1954     * This method uses the implementation in the decorators subpackage.
    1955     * </p>
    1956     *
    1957     * @param <C>        the type of object the {@link Collection} contains.
    1958     * @param collection The collection to make unmodifiable, must not be null.
    1959     * @return An unmodifiable collection backed by the given collection.
    1960     * @throws NullPointerException if the collection is null.
    1961     * @deprecated Since 4.1, use {@link java.util.Collections#unmodifiableCollection(Collection)} instead.
    1962     */
    1963    @Deprecated
    1964    public static <C> Collection<C> unmodifiableCollection(final Collection<? extends C> collection) {
    1965        Objects.requireNonNull(collection, "collection");
    1966        return UnmodifiableCollection.unmodifiableCollection(collection);
    1967    }
    1968
    1969    /**
    1970     * Don't allow instances.
    1971     */
    1972    private CollectionUtils() {
    1973        // empty
    1974    }
    1975}