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}