View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.collections4;
18  
19  import java.lang.reflect.Array;
20  import java.util.ArrayList;
21  import java.util.Collection;
22  import java.util.Collections;
23  import java.util.Comparator;
24  import java.util.Enumeration;
25  import java.util.HashMap;
26  import java.util.HashSet;
27  import java.util.Iterator;
28  import java.util.List;
29  import java.util.ListIterator;
30  import java.util.Map;
31  import java.util.Objects;
32  import java.util.Set;
33  
34  import org.apache.commons.collections4.collection.PredicatedCollection;
35  import org.apache.commons.collections4.collection.SynchronizedCollection;
36  import org.apache.commons.collections4.collection.TransformedCollection;
37  import org.apache.commons.collections4.collection.UnmodifiableBoundedCollection;
38  import org.apache.commons.collections4.collection.UnmodifiableCollection;
39  import org.apache.commons.collections4.functors.TruePredicate;
40  import org.apache.commons.collections4.iterators.CollatingIterator;
41  import org.apache.commons.collections4.iterators.PermutationIterator;
42  import org.apache.commons.collections4.multiset.HashMultiSet;
43  
44  /**
45   * Provides utility methods and decorators for {@link Collection} instances.
46   * <p>
47   * 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
48   * mandatory that the general contract of the {@link Object#hashCode()} method is maintained.
49   * </p>
50   * <p>
51   * NOTE: From 4.0, method parameters will take {@link Iterable} objects when possible.
52   * </p>
53   *
54   * @since 1.0
55   */
56  public class CollectionUtils {
57  
58      /**
59       * Helper class to easily access cardinality properties of two collections.
60       *
61       * @param <O> the element type.
62       */
63      private static class CardinalityHelper<O> {
64  
65          static boolean equals(final Collection<?> a, final Collection<?> b) {
66              return new HashMultiSet<>(a).equals(new HashMultiSet<>(b));
67          }
68  
69          /** Contains the cardinality for each object in collection A. */
70          final MultiSet<O> cardinalityA;
71  
72          /** Contains the cardinality for each object in collection B. */
73          final MultiSet<O> cardinalityB;
74  
75          /**
76           * Creates a new CardinalityHelper for two collections.
77           *
78           * @param a The first collection.
79           * @param b The second collection.
80           */
81          CardinalityHelper(final Iterable<? extends O> a, final Iterable<? extends O> b) {
82              cardinalityA = new HashMultiSet<>(a);
83              cardinalityB = new HashMultiSet<>(b);
84          }
85  
86          /**
87           * Gets the frequency of this object in collection A.
88           *
89           * @param key The key whose associated frequency is to be returned.
90           * @return The frequency of the object in collection A.
91           */
92          public int freqA(final Object key) {
93              return getFreq(key, cardinalityA);
94          }
95  
96          /**
97           * Gets the frequency of this object in collection B.
98           *
99           * @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 }