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