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