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.util.ArrayList;
20  import java.util.Collection;
21  import java.util.Collections;
22  import java.util.Comparator;
23  import java.util.Iterator;
24  import java.util.List;
25  import java.util.Set;
26  
27  import org.apache.commons.collections4.functors.EqualPredicate;
28  import org.apache.commons.collections4.iterators.LazyIteratorChain;
29  import org.apache.commons.collections4.iterators.ReverseListIterator;
30  import org.apache.commons.collections4.iterators.UniqueFilterIterator;
31  
32  /**
33   * Provides utility methods and decorators for {@link Iterable} instances.
34   * <p>
35   * <b>Note</b>: this util class has been designed for fail-fast argument checking.
36   * </p>
37   * <ul>
38   * <li>
39   * all decorator methods are <b>NOT</b> null-safe wrt the provided Iterable argument, i.e.
40   * they will throw a {@link NullPointerException} if a null Iterable is passed as argument.
41   * <li>
42   * all other utility methods are null-safe wrt the provided Iterable argument, i.e. they will
43   * treat a null Iterable the same way as an empty one. Other arguments which are null,
44   * e.g. a {@link Predicate}, will result in a {@link NullPointerException}. Exception: passing
45   * a null {@link Comparator} is equivalent to a Comparator with natural ordering.
46   * </ul>
47   *
48   * @since 4.1
49   */
50  public class IterableUtils {
51  
52      /**
53       * An empty iterable.
54       */
55      @SuppressWarnings("rawtypes")
56      static final FluentIterable EMPTY_ITERABLE = new FluentIterable<Object>() {
57          @Override
58          public Iterator<Object> iterator() {
59              return IteratorUtils.emptyIterator();
60          }
61      };
62  
63      // Empty
64      // ----------------------------------------------------------------------
65  
66      /**
67       * Gets an empty iterable.
68       * <p>
69       * This iterable does not contain any elements.
70       *
71       * @param <E> the element type
72       * @return an empty iterable
73       */
74      @SuppressWarnings("unchecked") // OK, empty collection is compatible with any type
75      public static <E> Iterable<E> emptyIterable() {
76          return EMPTY_ITERABLE;
77      }
78  
79      // Chained
80      // ----------------------------------------------------------------------
81  
82      /**
83       * Combines two iterables into a single iterable.
84       * <p>
85       * The returned iterable has an iterator that traverses the elements in {@code a},
86       * followed by the elements in {@code b}. The source iterators are not polled until
87       * necessary.
88       * <p>
89       * The returned iterable's iterator supports {@code remove()} when the corresponding
90       * input iterator supports it.
91       *
92       * @param <E> the element type
93       * @param a  the first iterable, may not be null
94       * @param b  the second iterable, may not be null
95       * @return a new iterable, combining the provided iterables
96       * @throws NullPointerException if either a or b is null
97       */
98      @SuppressWarnings("unchecked")
99      public static <E> Iterable<E> chainedIterable(final Iterable<? extends E> a,
100                                                   final Iterable<? extends E> b) {
101         return chainedIterable(new Iterable[] {a, b});
102     }
103 
104     /**
105      * Combines three iterables into a single iterable.
106      * <p>
107      * The returned iterable has an iterator that traverses the elements in {@code a},
108      * followed by the elements in {@code b} and {@code c}. The source iterators are
109      * not polled until necessary.
110      * <p>
111      * The returned iterable's iterator supports {@code remove()} when the corresponding
112      * input iterator supports it.
113      *
114      * @param <E> the element type
115      * @param a  the first iterable, may not be null
116      * @param b  the second iterable, may not be null
117      * @param c  the third iterable, may not be null
118      * @return a new iterable, combining the provided iterables
119      * @throws NullPointerException if either of the provided iterables is null
120      */
121     @SuppressWarnings("unchecked")
122     public static <E> Iterable<E> chainedIterable(final Iterable<? extends E> a,
123                                                   final Iterable<? extends E> b,
124                                                   final Iterable<? extends E> c) {
125         return chainedIterable(new Iterable[] {a, b, c});
126     }
127 
128     /**
129      * Combines four iterables into a single iterable.
130      * <p>
131      * The returned iterable has an iterator that traverses the elements in {@code a},
132      * followed by the elements in {@code b}, {@code c} and {@code d}. The source
133      * iterators are not polled until necessary.
134      * <p>
135      * The returned iterable's iterator supports {@code remove()} when the corresponding
136      * input iterator supports it.
137      *
138      * @param <E> the element type
139      * @param a  the first iterable, may not be null
140      * @param b  the second iterable, may not be null
141      * @param c  the third iterable, may not be null
142      * @param d  the fourth iterable, may not be null
143      * @return a new iterable, combining the provided iterables
144      * @throws NullPointerException if either of the provided iterables is null
145      */
146     @SuppressWarnings("unchecked")
147     public static <E> Iterable<E> chainedIterable(final Iterable<? extends E> a,
148                                                   final Iterable<? extends E> b,
149                                                   final Iterable<? extends E> c,
150                                                   final Iterable<? extends E> d) {
151         return chainedIterable(new Iterable[] {a, b, c, d});
152     }
153 
154     /**
155      * Combines the provided iterables into a single iterable.
156      * <p>
157      * The returned iterable has an iterator that traverses the elements in the order
158      * of the arguments, i.e. iterables[0], iterables[1], .... The source iterators
159      * are not polled until necessary.
160      * <p>
161      * The returned iterable's iterator supports {@code remove()} when the corresponding
162      * input iterator supports it.
163      *
164      * @param <E> the element type
165      * @param iterables  the iterables to combine, may not be null
166      * @return a new iterable, combining the provided iterables
167      * @throws NullPointerException if either of the provided iterables is null
168      */
169     public static <E> Iterable<E> chainedIterable(final Iterable<? extends E>... iterables) {
170         checkNotNull(iterables);
171         return new FluentIterable<E>() {
172             @Override
173             public Iterator<E> iterator() {
174                 return new LazyIteratorChain<E>() {
175                     @Override
176                     protected Iterator<? extends E> nextIterator(final int count) {
177                         if (count > iterables.length) {
178                             return null;
179                         }
180                         return iterables[count - 1].iterator();
181                     }
182                 };
183             }
184         };
185     }
186 
187     // Collated
188     // ----------------------------------------------------------------------
189 
190     /**
191      * Combines the two provided iterables into an ordered iterable using
192      * natural ordering.
193      * <p>
194      * The returned iterable's iterator supports {@code remove()} when the
195      * corresponding input iterator supports it.
196      *
197      * @param <E> the element type
198      * @param a  the first iterable, may not be null
199      * @param b  the second iterable, may not be null
200      * @return a filtered view on the specified iterable
201      * @throws NullPointerException if either of the provided iterables is null
202      */
203     public static <E> Iterable<E> collatedIterable(final Iterable<? extends E> a,
204                                                    final Iterable<? extends E> b) {
205         checkNotNull(a, b);
206         return new FluentIterable<E>() {
207             @Override
208             public Iterator<E> iterator() {
209                 return IteratorUtils.collatedIterator(null, a.iterator(), b.iterator());
210             }
211         };
212     }
213 
214     /**
215      * Combines the two provided iterables into an ordered iterable using the
216      * provided comparator. If the comparator is null, natural ordering will be
217      * used.
218      * <p>
219      * The returned iterable's iterator supports {@code remove()} when the
220      * corresponding input iterator supports it.
221      *
222      * @param <E> the element type
223      * @param comparator  the comparator defining an ordering over the elements,
224      *   may be null, in which case natural ordering will be used
225      * @param a  the first iterable, may not be null
226      * @param b  the second iterable, may not be null
227      * @return a filtered view on the specified iterable
228      * @throws NullPointerException if either of the provided iterables is null
229      */
230     public static <E> Iterable<E> collatedIterable(final Comparator<? super E> comparator,
231                                                    final Iterable<? extends E> a,
232                                                    final Iterable<? extends E> b) {
233         checkNotNull(a, b);
234         return new FluentIterable<E>() {
235             @Override
236             public Iterator<E> iterator() {
237                 return IteratorUtils.collatedIterator(comparator, a.iterator(), b.iterator());
238             }
239         };
240     }
241 
242     // Filtered
243     // ----------------------------------------------------------------------
244 
245     /**
246      * Returns a view of the given iterable that only contains elements matching
247      * the provided predicate.
248      * <p>
249      * The returned iterable's iterator supports {@code remove()} when the
250      * corresponding input iterator supports it.
251      *
252      * @param <E> the element type
253      * @param iterable  the iterable to filter, may not be null
254      * @param predicate  the predicate used to filter elements, may not be null
255      * @return a filtered view on the specified iterable
256      * @throws NullPointerException if either iterable or predicate is null
257      */
258     public static <E> Iterable<E> filteredIterable(final Iterable<E> iterable,
259                                                    final Predicate<? super E> predicate) {
260         checkNotNull(iterable);
261         if (predicate == null) {
262             throw new NullPointerException("Predicate must not be null.");
263         }
264         return new FluentIterable<E>() {
265             @Override
266             public Iterator<E> iterator() {
267                 return IteratorUtils.filteredIterator(emptyIteratorIfNull(iterable), predicate);
268             }
269         };
270     }
271 
272     // Bounded
273     // ----------------------------------------------------------------------
274 
275     /**
276      * Returns a view of the given iterable that contains at most the given number
277      * of elements.
278      * <p>
279      * The returned iterable's iterator supports {@code remove()} when the corresponding
280      * input iterator supports it.
281      *
282      * @param <E> the element type
283      * @param iterable  the iterable to limit, may not be null
284      * @param maxSize  the maximum number of elements, must not be negative
285      * @return a bounded view on the specified iterable
286      * @throws IllegalArgumentException if maxSize is negative
287      * @throws NullPointerException if iterable is null
288      */
289     public static <E> Iterable<E> boundedIterable(final Iterable<E> iterable, final long maxSize) {
290         checkNotNull(iterable);
291         if (maxSize < 0) {
292             throw new IllegalArgumentException("MaxSize parameter must not be negative.");
293         }
294 
295         return new FluentIterable<E>() {
296             @Override
297             public Iterator<E> iterator() {
298                 return IteratorUtils.boundedIterator(iterable.iterator(), maxSize);
299             }
300         };
301     }
302 
303     // Looping
304     // ----------------------------------------------------------------------
305 
306     /**
307      * Returns a view of the given iterable which will cycle infinitely over
308      * its elements.
309      * <p>
310      * The returned iterable's iterator supports {@code remove()} if
311      * {@code iterable.iterator()} does. After {@code remove()} is called, subsequent
312      * cycles omit the removed element, which is no longer in {@code iterable}. The
313      * iterator's {@code hasNext()} method returns {@code true} until {@code iterable}
314      * is empty.
315      *
316      * @param <E> the element type
317      * @param iterable  the iterable to loop, may not be null
318      * @return a view of the iterable, providing an infinite loop over its elements
319      * @throws NullPointerException if iterable is null
320      */
321     public static <E> Iterable<E> loopingIterable(final Iterable<E> iterable) {
322         checkNotNull(iterable);
323         return new FluentIterable<E>() {
324             @Override
325             public Iterator<E> iterator() {
326                 return new LazyIteratorChain<E>() {
327                     @Override
328                     protected Iterator<? extends E> nextIterator(final int count) {
329                         if (IterableUtils.isEmpty(iterable)) {
330                             return null;
331                         }
332                         return iterable.iterator();
333                     }
334                 };
335             }
336         };
337     }
338 
339     // Reversed
340     // ----------------------------------------------------------------------
341 
342     /**
343      * Returns a reversed view of the given iterable.
344      * <p>
345      * In case the provided iterable is a {@link List} instance, a
346      * {@link ReverseListIterator} will be used to reverse the traversal
347      * order, otherwise an intermediate {@link List} needs to be created.
348      * <p>
349      * The returned iterable's iterator supports {@code remove()} if the
350      * provided iterable is a {@link List} instance.
351      *
352      * @param <E> the element type
353      * @param iterable  the iterable to use, may not be null
354      * @return a reversed view of the specified iterable
355      * @throws NullPointerException if iterable is null
356      * @see ReverseListIterator
357      */
358     public static <E> Iterable<E> reversedIterable(final Iterable<E> iterable) {
359         checkNotNull(iterable);
360         return new FluentIterable<E>() {
361             @Override
362             public Iterator<E> iterator() {
363                 final List<E> list = (iterable instanceof List<?>) ?
364                         (List<E>) iterable :
365                         IteratorUtils.toList(iterable.iterator());
366                 return new ReverseListIterator<>(list);
367             }
368         };
369     }
370 
371     // Skipping
372     // ----------------------------------------------------------------------
373 
374     /**
375      * Returns a view of the given iterable that skips the first N elements.
376      * <p>
377      * The returned iterable's iterator supports {@code remove()} when the corresponding
378      * input iterator supports it.
379      *
380      * @param <E> the element type
381      * @param iterable  the iterable to use, may not be null
382      * @param elementsToSkip  the number of elements to skip from the start, must not be negative
383      * @return a view of the specified iterable, skipping the first N elements
384      * @throws IllegalArgumentException if elementsToSkip is negative
385      * @throws NullPointerException if iterable is null
386      */
387     public static <E> Iterable<E> skippingIterable(final Iterable<E> iterable, final long elementsToSkip) {
388         checkNotNull(iterable);
389         if (elementsToSkip < 0) {
390             throw new IllegalArgumentException("ElementsToSkip parameter must not be negative.");
391         }
392 
393         return new FluentIterable<E>() {
394             @Override
395             public Iterator<E> iterator() {
396                 return IteratorUtils.skippingIterator(iterable.iterator(), elementsToSkip);
397             }
398         };
399     }
400 
401     // Transformed
402     // ----------------------------------------------------------------------
403 
404     /**
405      * Returns a transformed view of the given iterable where all of its elements
406      * have been transformed by the provided transformer.
407      * <p>
408      * The returned iterable's iterator supports {@code remove()} when the corresponding
409      * input iterator supports it.
410      *
411      * @param <I>  the input element type
412      * @param <O>  the output element type
413      * @param iterable  the iterable to transform, may not be null
414      * @param transformer  the transformer, must not be null
415      * @return a transformed view of the specified iterable
416      * @throws NullPointerException if either iterable or transformer is null
417      */
418     public static <I, O> Iterable<O> transformedIterable(final Iterable<I> iterable,
419                                                          final Transformer<? super I, ? extends O> transformer) {
420         checkNotNull(iterable);
421         if (transformer == null) {
422             throw new NullPointerException("Transformer must not be null.");
423         }
424         return new FluentIterable<O>() {
425             @Override
426             public Iterator<O> iterator() {
427                 return IteratorUtils.transformedIterator(iterable.iterator(), transformer);
428             }
429         };
430     }
431 
432     // Unique
433     // ----------------------------------------------------------------------
434 
435     /**
436      * Returns a unique view of the given iterable.
437      * <p>
438      * The returned iterable's iterator supports {@code remove()} when the
439      * corresponding input iterator supports it. Calling {@code remove()}
440      * will only remove a single element from the underlying iterator.
441      *
442      * @param <E> the element type
443      * @param iterable  the iterable to use, may not be null
444      * @return a unique view of the specified iterable
445      * @throws NullPointerException if iterable is null
446      */
447     public static <E> Iterable<E> uniqueIterable(final Iterable<E> iterable) {
448         checkNotNull(iterable);
449         return new FluentIterable<E>() {
450             @Override
451             public Iterator<E> iterator() {
452                 return new UniqueFilterIterator<>(iterable.iterator());
453             }
454         };
455     }
456 
457     // Unmodifiable
458     // ----------------------------------------------------------------------
459 
460     /**
461      * Returns an unmodifiable view of the given iterable.
462      * <p>
463      * The returned iterable's iterator does not support {@code remove()}.
464      *
465      * @param <E> the element type
466      * @param iterable  the iterable to use, may not be null
467      * @return an unmodifiable view of the specified iterable
468      * @throws NullPointerException if iterable is null
469      */
470     public static <E> Iterable<E> unmodifiableIterable(final Iterable<E> iterable) {
471         checkNotNull(iterable);
472         if (iterable instanceof UnmodifiableIterable<?>) {
473             return iterable;
474         }
475         return new UnmodifiableIterable<>(iterable);
476     }
477 
478     /**
479      * Inner class to distinguish unmodifiable instances.
480      */
481     private static final class UnmodifiableIterable<E> extends FluentIterable<E> {
482         private final Iterable<E> unmodifiable;
483 
484         public UnmodifiableIterable(final Iterable<E> iterable) {
485             super();
486             this.unmodifiable = iterable;
487         }
488 
489         @Override
490         public Iterator<E> iterator() {
491             return IteratorUtils.unmodifiableIterator(unmodifiable.iterator());
492         }
493     }
494 
495     // Zipping
496     // ----------------------------------------------------------------------
497 
498     /**
499      * Interleaves two iterables into a single iterable.
500      * <p>
501      * The returned iterable has an iterator that traverses the elements in {@code a}
502      * and {@code b} in alternating order. The source iterators are not polled until
503      * necessary.
504      * <p>
505      * The returned iterable's iterator supports {@code remove()} when the corresponding
506      * input iterator supports it.
507      *
508      * @param <E> the element type
509      * @param a  the first iterable, may not be null
510      * @param b  the second iterable, may not be null
511      * @return a new iterable, interleaving the provided iterables
512      * @throws NullPointerException if either a or b is null
513      */
514     public static <E> Iterable<E> zippingIterable(final Iterable<? extends E> a,
515                                                   final Iterable<? extends E> b) {
516         checkNotNull(a);
517         checkNotNull(b);
518         return new FluentIterable<E>() {
519             @Override
520             public Iterator<E> iterator() {
521                 return IteratorUtils.zippingIterator(a.iterator(), b.iterator());
522             }
523         };
524     }
525 
526     /**
527      * Interleaves two iterables into a single iterable.
528      * <p>
529      * The returned iterable has an iterator that traverses the elements in {@code a}
530      * and {@code b} in alternating order. The source iterators are not polled until
531      * necessary.
532      * <p>
533      * The returned iterable's iterator supports {@code remove()} when the corresponding
534      * input iterator supports it.
535      *
536      * @param <E> the element type
537      * @param first  the first iterable, may not be null
538      * @param others  the array of iterables to interleave, may not be null
539      * @return a new iterable, interleaving the provided iterables
540      * @throws NullPointerException if either of the provided iterables is null
541      */
542     public static <E> Iterable<E> zippingIterable(final Iterable<? extends E> first,
543                                                   final Iterable<? extends E>... others) {
544         checkNotNull(first);
545         checkNotNull(others);
546         return new FluentIterable<E>() {
547             @Override
548             public Iterator<E> iterator() {
549                 @SuppressWarnings("unchecked") // safe
550                 final
551                 Iterator<? extends E>[] iterators = new Iterator[others.length + 1];
552                 iterators[0] = first.iterator();
553                 for (int i = 0; i < others.length; i++) {
554                     iterators[i + 1] = others[i].iterator();
555                 }
556                 return IteratorUtils.zippingIterator(iterators);
557             }
558         };
559     }
560 
561     // Utility methods
562     // ----------------------------------------------------------------------
563 
564     /**
565      * Returns an immutable empty iterable if the argument is null,
566      * or the argument itself otherwise.
567      *
568      * @param <E> the element type
569      * @param iterable  the iterable, may be null
570      * @return an empty iterable if the argument is null
571      */
572     public static <E> Iterable<E> emptyIfNull(final Iterable<E> iterable) {
573         return iterable == null ? IterableUtils.<E>emptyIterable() : iterable;
574     }
575 
576     /**
577      * Applies the closure to each element of the provided iterable.
578      *
579      * @param <E> the element type
580      * @param iterable  the iterator to use, may be null
581      * @param closure  the closure to apply to each element, may not be null
582      * @throws NullPointerException if closure is null
583      */
584     public static <E> void forEach(final Iterable<E> iterable, final Closure<? super E> closure) {
585         IteratorUtils.forEach(emptyIteratorIfNull(iterable), closure);
586     }
587 
588     /**
589      * Executes the given closure on each but the last element in the iterable.
590      * <p>
591      * If the input iterable is null no change is made.
592      *
593      * @param <E> the type of object the {@link Iterable} contains
594      * @param iterable  the iterable to get the input from, may be null
595      * @param closure  the closure to perform, may not be null
596      * @return the last element in the iterable, or null if iterable is null or empty
597      */
598     public static <E> E forEachButLast(final Iterable<E> iterable, final Closure<? super E> closure) {
599         return IteratorUtils.forEachButLast(emptyIteratorIfNull(iterable), closure);
600     }
601 
602     /**
603      * Finds the first element in the given iterable which matches the given predicate.
604      * <p>
605      * A <code>null</code> or empty iterator returns null.
606      *
607      * @param <E> the element type
608      * @param iterable  the iterable to search, may be null
609      * @param predicate  the predicate to use, may not be null
610      * @return the first element of the iterable which matches the predicate or null if none could be found
611      * @throws NullPointerException if predicate is null
612      */
613     public static <E> E find(final Iterable<E> iterable, final Predicate<? super E> predicate) {
614         return IteratorUtils.find(emptyIteratorIfNull(iterable), predicate);
615     }
616 
617     /**
618      * Returns the index of the first element in the specified iterable that
619      * matches the given predicate.
620      * <p>
621      * A <code>null</code> or empty iterable returns -1.
622      *
623      * @param <E> the element type
624      * @param iterable  the iterable to search, may be null
625      * @param predicate  the predicate to use, may not be null
626      * @return the index of the first element which matches the predicate or -1 if none matches
627      * @throws NullPointerException if predicate is null
628      */
629     public static <E> int indexOf(final Iterable<E> iterable, final Predicate<? super E> predicate) {
630         return IteratorUtils.indexOf(emptyIteratorIfNull(iterable), predicate);
631     }
632 
633     /**
634      * Answers true if a predicate is true for every element of an iterable.
635      * <p>
636      * A <code>null</code> or empty iterable returns true.
637      *
638      * @param <E> the type of object the {@link Iterable} contains
639      * @param iterable  the {@link Iterable} to use, may be null
640      * @param predicate  the predicate to use, may not be null
641      * @return true if every element of the collection matches the predicate or if the
642      *   collection is empty, false otherwise
643      * @throws NullPointerException if predicate is null
644      */
645     public static <E> boolean matchesAll(final Iterable<E> iterable, final Predicate<? super E> predicate) {
646         return IteratorUtils.matchesAll(emptyIteratorIfNull(iterable), predicate);
647     }
648 
649     /**
650      * Answers true if a predicate is true for any element of the iterable.
651      * <p>
652      * A <code>null</code> or empty iterable returns false.
653      *
654      * @param <E> the type of object the {@link Iterable} contains
655      * @param iterable  the {@link Iterable} to use, may be null
656      * @param predicate  the predicate to use, may not be null
657      * @return true if any element of the collection matches the predicate, false otherwise
658      * @throws NullPointerException if predicate is null
659      */
660     public static <E> boolean matchesAny(final Iterable<E> iterable, final Predicate<? super E> predicate) {
661         return IteratorUtils.matchesAny(emptyIteratorIfNull(iterable), predicate);
662     }
663 
664     /**
665      * Counts the number of elements in the input iterable that match the predicate.
666      * <p>
667      * A <code>null</code> iterable matches no elements.
668      *
669      * @param <E> the type of object the {@link Iterable} contains
670      * @param input  the {@link Iterable} to get the input from, may be null
671      * @param predicate  the predicate to use, may not be null
672      * @return the number of matches for the predicate in the collection
673      * @throws NullPointerException if predicate is null
674      */
675     public static <E> long countMatches(final Iterable<E> input, final Predicate<? super E> predicate) {
676         if (predicate == null) {
677             throw new NullPointerException("Predicate must not be null.");
678         }
679         return size(filteredIterable(emptyIfNull(input), predicate));
680     }
681 
682     /**
683      * Answers true if the provided iterable is empty.
684      * <p>
685      * A <code>null</code> iterable returns true.
686      *
687      * @param iterable  the {@link Iterable to use}, may be null
688      * @return true if the iterable is null or empty, false otherwise
689      */
690     public static boolean isEmpty(final Iterable<?> iterable) {
691         if (iterable instanceof Collection<?>) {
692             return ((Collection<?>) iterable).isEmpty();
693         }
694         return IteratorUtils.isEmpty(emptyIteratorIfNull(iterable));
695     }
696 
697     /**
698      * Checks if the object is contained in the given iterable.
699      * <p>
700      * A <code>null</code> or empty iterable returns false.
701      *
702      * @param <E> the type of object the {@link Iterable} contains
703      * @param iterable  the iterable to check, may be null
704      * @param object  the object to check
705      * @return true if the object is contained in the iterable, false otherwise
706      */
707     public static <E> boolean contains(final Iterable<E> iterable, final Object object) {
708         if (iterable instanceof Collection<?>) {
709             return ((Collection<E>) iterable).contains(object);
710         }
711         return IteratorUtils.contains(emptyIteratorIfNull(iterable), object);
712     }
713 
714     /**
715      * Checks if the object is contained in the given iterable. Object equality
716      * is tested with an {@code equator} unlike {@link #contains(Iterable, Object)}
717      * which uses {@link Object#equals(Object)}.
718      * <p>
719      * A <code>null</code> or empty iterable returns false.
720      * A <code>null</code> object will not be passed to the equator, instead a
721      * {@link org.apache.commons.collections4.functors.NullPredicate NullPredicate}
722      * will be used.
723      *
724      * @param <E> the type of object the {@link Iterable} contains
725      * @param iterable  the iterable to check, may be null
726      * @param object  the object to check
727      * @param equator  the equator to use to check, may not be null
728      * @return true if the object is contained in the iterable, false otherwise
729      * @throws NullPointerException if equator is null
730      */
731     public static <E> boolean contains(final Iterable<? extends E> iterable, final E object,
732                                        final Equator<? super E> equator) {
733         if (equator == null) {
734             throw new NullPointerException("Equator must not be null.");
735         }
736         return matchesAny(iterable, EqualPredicate.equalPredicate(object, equator));
737     }
738 
739     /**
740      * Returns the number of occurrences of the provided object in the iterable.
741      *
742      * @param <E> the element type that the {@link Iterable} may contain
743      * @param <T> the element type of the object to find
744      * @param iterable  the {@link Iterable} to search
745      * @param obj  the object to find the cardinality of
746      * @return the number of occurrences of obj in iterable
747      */
748     public static <E, T extends E> int frequency(final Iterable<E> iterable, final T obj) {
749         if (iterable instanceof Set<?>) {
750             return ((Set<E>) iterable).contains(obj) ? 1 : 0;
751         }
752         if (iterable instanceof Bag<?>) {
753             return ((Bag<E>) iterable).getCount(obj);
754         }
755         return size(filteredIterable(emptyIfNull(iterable), EqualPredicate.<E>equalPredicate(obj)));
756     }
757 
758     /**
759      * Returns the <code>index</code>-th value in the <code>iterable</code>'s {@link Iterator}, throwing
760      * <code>IndexOutOfBoundsException</code> if there is no such element.
761      * <p>
762      * If the {@link Iterable} is a {@link List}, then it will use {@link List#get(int)}.
763      *
764      * @param <T> the type of object in the {@link Iterable}.
765      * @param iterable  the {@link Iterable} to get a value from, may be null
766      * @param index  the index to get
767      * @return the object at the specified index
768      * @throws IndexOutOfBoundsException if the index is invalid
769      */
770     public static <T> T get(final Iterable<T> iterable, final int index) {
771         CollectionUtils.checkIndexBounds(index);
772         if (iterable instanceof List<?>) {
773             return ((List<T>) iterable).get(index);
774         }
775         return IteratorUtils.get(emptyIteratorIfNull(iterable), index);
776     }
777 
778     /**
779      * Shortcut for {@code get(iterator, 0)}.
780      * <p>
781      * Returns the <code>first</code> value in the <code>iterable</code>'s {@link Iterator}, throwing
782      * <code>IndexOutOfBoundsException</code> if there is no such element.
783      * </p>
784      * <p>
785      * If the {@link Iterable} is a {@link List}, then it will use {@link List#get(int)}.
786      * </p>
787      *
788      * @param <T> the type of object in the {@link Iterable}.
789      * @param iterable  the {@link Iterable} to get a value from, may be null
790      * @return the first object
791      * @throws IndexOutOfBoundsException if the request  is invalid
792      * @since 4.2
793      */
794     public static <T> T first(final Iterable<T> iterable) {
795         return get(iterable, 0);
796     }
797 
798     /**
799      * Returns the number of elements contained in the given iterator.
800      * <p>
801      * A <code>null</code> or empty iterator returns {@code 0}.
802      *
803      * @param iterable  the iterable to check, may be null
804      * @return the number of elements contained in the iterable
805      */
806     public static int size(final Iterable<?> iterable) {
807         if (iterable instanceof Collection<?>) {
808             return ((Collection<?>) iterable).size();
809         }
810         return IteratorUtils.size(emptyIteratorIfNull(iterable));
811     }
812 
813     /**
814      * Partitions all elements from iterable into separate output collections,
815      * based on the evaluation of the given predicate.
816      * <p>
817      * For each predicate, the result will contain a list holding all elements of the
818      * input iterable matching the predicate. The last list will hold all elements
819      * which didn't match any predicate:
820      * <pre>
821      *  [C1, R] = partition(I, P1) with
822      *  I = input
823      *  P1 = first predicate
824      *  C1 = collection of elements matching P1
825      *  R = collection of elements rejected by all predicates
826      * </pre>
827      * <p>
828      * If the input iterable is <code>null</code>, the same is returned as for an
829      * empty iterable.
830      * <p>
831      * Example: for an input list [1, 2, 3, 4, 5] calling partition with a predicate [x &lt; 3]
832      * will result in the following output: [[1, 2], [3, 4, 5]].
833      *
834      * @param <O>  the type of object the {@link Iterable} contains
835      * @param iterable  the iterable to partition, may be null
836      * @param predicate  the predicate to use, may not be null
837      * @return a list containing the output collections
838      * @throws NullPointerException if predicate is null
839      */
840     public static <O> List<List<O>> partition(final Iterable<? extends O> iterable,
841                                               final Predicate<? super O> predicate) {
842         if (predicate == null) {
843             throw new NullPointerException("Predicate must not be null.");
844         }
845         @SuppressWarnings({ "unchecked", "rawtypes" }) // safe
846         final Factory<List<O>> factory = FactoryUtils.instantiateFactory((Class) ArrayList.class);
847         @SuppressWarnings("unchecked") // safe
848         final Predicate<? super O>[] predicates = new Predicate[] { predicate };
849         return partition(iterable, factory, predicates);
850     }
851 
852     /**
853      * Partitions all elements from iterable into separate output collections,
854      * based on the evaluation of the given predicates.
855      * <p>
856      * For each predicate, the result will contain a list holding all elements of the
857      * input iterable matching the predicate. The last list will hold all elements
858      * which didn't match any predicate:
859      * <pre>
860      *  [C1, C2, R] = partition(I, P1, P2) with
861      *  I = input
862      *  P1 = first predicate
863      *  P2 = second predicate
864      *  C1 = collection of elements matching P1
865      *  C2 = collection of elements matching P2
866      *  R = collection of elements rejected by all predicates
867      * </pre>
868      * <p>
869      * <b>Note</b>: elements are only added to the output collection of the first matching
870      * predicate, determined by the order of arguments.
871      * <p>
872      * If the input iterable is <code>null</code>, the same is returned as for an
873      * empty iterable.
874      * <p>
875      * Example: for an input list [1, 2, 3, 4, 5] calling partition with predicates [x &lt; 3]
876      * and [x &lt; 5] will result in the following output: [[1, 2], [3, 4], [5]].
877      *
878      * @param <O>  the type of object the {@link Iterable} contains
879      * @param iterable  the collection to get the input from, may be null
880      * @param predicates  the predicates to use, may not be null
881      * @return a list containing the output collections
882      * @throws NullPointerException if any predicate is null
883      */
884     public static <O> List<List<O>> partition(final Iterable<? extends O> iterable,
885                                               final Predicate<? super O>... predicates) {
886 
887         @SuppressWarnings({ "unchecked", "rawtypes" }) // safe
888         final Factory<List<O>> factory = FactoryUtils.instantiateFactory((Class) ArrayList.class);
889         return partition(iterable, factory, predicates);
890     }
891 
892     /**
893      * Partitions all elements from iterable into separate output collections,
894      * based on the evaluation of the given predicates.
895      * <p>
896      * For each predicate, the returned list will contain a collection holding
897      * all elements of the input iterable matching the predicate. The last collection
898      * contained in the list will hold all elements which didn't match any predicate:
899      * <pre>
900      *  [C1, C2, R] = partition(I, P1, P2) with
901      *  I = input
902      *  P1 = first predicate
903      *  P2 = second predicate
904      *  C1 = collection of elements matching P1
905      *  C2 = collection of elements matching P2
906      *  R = collection of elements rejected by all predicates
907      * </pre>
908      * <p>
909      * <b>Note</b>: elements are only added to the output collection of the first matching
910      * predicate, determined by the order of arguments.
911      * <p>
912      * If the input iterable is <code>null</code>, the same is returned as for an
913      * empty iterable.
914      * If no predicates have been provided, all elements of the input collection
915      * will be added to the rejected collection.
916      * <p>
917      * Example: for an input list [1, 2, 3, 4, 5] calling partition with predicates [x &lt; 3]
918      * and [x &lt; 5] will result in the following output: [[1, 2], [3, 4], [5]].
919      *
920      * @param <O>  the type of object the {@link Iterable} contains
921      * @param <R>  the type of the output {@link Collection}
922      * @param iterable  the collection to get the input from, may be null
923      * @param partitionFactory  the factory used to create the output collections
924      * @param predicates  the predicates to use, may not be null
925      * @return a list containing the output collections
926      * @throws NullPointerException if any predicate is null
927      */
928     public static <O, R extends Collection<O>> List<R> partition(final Iterable<? extends O> iterable,
929             final Factory<R> partitionFactory, final Predicate<? super O>... predicates) {
930 
931         if (iterable == null) {
932             final Iterable<O> empty = emptyIterable();
933             return partition(empty, partitionFactory, predicates);
934         }
935 
936         if (predicates == null) {
937             throw new NullPointerException("Predicates must not be null.");
938         }
939 
940         for (final Predicate<?> p : predicates) {
941             if (p == null) {
942                 throw new NullPointerException("Predicate must not be null.");
943             }
944         }
945 
946         if (predicates.length < 1) {
947             // return the entire input collection as a single partition
948             final R singlePartition = partitionFactory.create();
949             CollectionUtils.addAll(singlePartition, iterable);
950             return Collections.singletonList(singlePartition);
951         }
952 
953         // create the empty partitions
954         final int numberOfPredicates = predicates.length;
955         final int numberOfPartitions = numberOfPredicates + 1;
956         final List<R> partitions = new ArrayList<>(numberOfPartitions);
957         for (int i = 0; i < numberOfPartitions; ++i) {
958             partitions.add(partitionFactory.create());
959         }
960 
961         // for each element in inputCollection:
962         // find the first predicate that evaluates to true.
963         // if there is a predicate, add the element to the corresponding partition.
964         // if there is no predicate, add it to the last, catch-all partition.
965         for (final O element : iterable) {
966             boolean elementAssigned = false;
967             for (int i = 0; i < numberOfPredicates; ++i) {
968                 if (predicates[i].evaluate(element)) {
969                     partitions.get(i).add(element);
970                     elementAssigned = true;
971                     break;
972                 }
973             }
974 
975             if (!elementAssigned) {
976                 // no predicates evaluated to true
977                 // add element to last partition
978                 partitions.get(numberOfPredicates).add(element);
979             }
980         }
981 
982         return partitions;
983     }
984 
985     /**
986      * Gets a new list with the contents of the provided iterable.
987      *
988      * @param <E> the element type
989      * @param iterable  the iterable to use, may be null
990      * @return a list of the iterator contents
991      */
992     public static <E> List<E> toList(final Iterable<E> iterable) {
993         return IteratorUtils.toList(emptyIteratorIfNull(iterable));
994     }
995 
996     /**
997      * Returns a string representation of the elements of the specified iterable.
998      * <p>
999      * The string representation consists of a list of the iterable's elements,
1000      * enclosed in square brackets ({@code "[]"}). Adjacent elements are separated
1001      * by the characters {@code ", "} (a comma followed by a space). Elements are
1002      * converted to strings as by {@code String.valueOf(Object)}.
1003      *
1004      * @param <E> the element type
1005      * @param iterable  the iterable to convert to a string, may be null
1006      * @return a string representation of {@code iterable}
1007      */
1008     public static <E> String toString(final Iterable<E> iterable) {
1009         return IteratorUtils.toString(emptyIteratorIfNull(iterable));
1010     }
1011 
1012     /**
1013      * Returns a string representation of the elements of the specified iterable.
1014      * <p>
1015      * The string representation consists of a list of the iterable's elements,
1016      * enclosed in square brackets ({@code "[]"}). Adjacent elements are separated
1017      * by the characters {@code ", "} (a comma followed by a space). Elements are
1018      * converted to strings as by using the provided {@code transformer}.
1019      *
1020      * @param <E> the element type
1021      * @param iterable  the iterable to convert to a string, may be null
1022      * @param transformer  the transformer used to get a string representation of an element
1023      * @return a string representation of {@code iterable}
1024      * @throws NullPointerException if {@code transformer} is null
1025      */
1026     public static <E> String toString(final Iterable<E> iterable,
1027                                       final Transformer<? super E, String> transformer) {
1028         if (transformer == null) {
1029             throw new NullPointerException("Transformer must not be null.");
1030         }
1031         return IteratorUtils.toString(emptyIteratorIfNull(iterable), transformer);
1032     }
1033 
1034     /**
1035      * Returns a string representation of the elements of the specified iterable.
1036      * <p>
1037      * The string representation consists of a list of the iterable's elements,
1038      * enclosed by the provided {@code prefix} and {@code suffix}. Adjacent elements
1039      * are separated by the provided {@code delimiter}. Elements are converted to
1040      * strings as by using the provided {@code transformer}.
1041      *
1042      * @param <E> the element type
1043      * @param iterable  the iterable to convert to a string, may be null
1044      * @param transformer  the transformer used to get a string representation of an element
1045      * @param delimiter  the string to delimit elements
1046      * @param prefix  the prefix, prepended to the string representation
1047      * @param suffix  the suffix, appended to the string representation
1048      * @return a string representation of {@code iterable}
1049      * @throws NullPointerException if either transformer, delimiter, prefix or suffix is null
1050      */
1051     public static <E> String toString(final Iterable<E> iterable,
1052                                       final Transformer<? super E, String> transformer,
1053                                       final String delimiter,
1054                                       final String prefix,
1055                                       final String suffix) {
1056         return IteratorUtils.toString(emptyIteratorIfNull(iterable),
1057                                       transformer, delimiter, prefix, suffix);
1058     }
1059 
1060     // Helper methods
1061     // ----------------------------------------------------------------------
1062 
1063     /**
1064      * Fail-fast check for null arguments.
1065      *
1066      * @param iterable  the iterable to check
1067      * @throws NullPointerException if iterable is null
1068      */
1069     static void checkNotNull(final Iterable<?> iterable) {
1070         if (iterable == null) {
1071             throw new NullPointerException("Iterable must not be null.");
1072         }
1073     }
1074 
1075     /**
1076      * Fail-fast check for null arguments.
1077      *
1078      * @param iterables  the iterables to check
1079      * @throws NullPointerException if the argument or any of its contents is null
1080      */
1081     static void checkNotNull(final Iterable<?>... iterables) {
1082         if (iterables == null) {
1083             throw new NullPointerException("Iterables must not be null.");
1084         }
1085         for (final Iterable<?> iterable : iterables) {
1086             checkNotNull(iterable);
1087         }
1088     }
1089 
1090     /**
1091      * Returns an empty iterator if the argument is <code>null</code>,
1092      * or {@code iterable.iterator()} otherwise.
1093      *
1094      * @param <E> the element type
1095      * @param iterable  the iterable, possibly <code>null</code>
1096      * @return an empty iterator if the argument is <code>null</code>
1097      */
1098     private static <E> Iterator<E> emptyIteratorIfNull(final Iterable<E> iterable) {
1099         return iterable != null ? iterable.iterator() : IteratorUtils.<E>emptyIterator();
1100     }
1101 
1102 }