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