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