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 < 3] and [x < 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 < 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 < 3] and [x < 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 }