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