001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * https://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.collections4; 019 020import java.util.ArrayList; 021import java.util.Collection; 022import java.util.Collections; 023import java.util.Comparator; 024import java.util.HashSet; 025import java.util.Iterator; 026import java.util.LinkedHashSet; 027import java.util.List; 028import java.util.Objects; 029import java.util.Set; 030import java.util.function.ToIntFunction; 031 032import org.apache.commons.collections4.functors.EqualPredicate; 033import org.apache.commons.collections4.functors.NullPredicate; 034import org.apache.commons.collections4.iterators.LazyIteratorChain; 035import org.apache.commons.collections4.iterators.ReverseListIterator; 036import org.apache.commons.collections4.iterators.UniqueFilterIterator; 037 038/** 039 * Provides utility methods and decorators for {@link Iterable} instances. 040 * <p> 041 * <strong>Note</strong>: This utility class has been designed with fail-fast argument checking. 042 * </p> 043 * <ul> 044 * <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 045 * null Iterable is passed as argument.</li> 046 * <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. 047 * For other arguments which are null, a {@link Predicate} will result in a {@link NullPointerException}. Exception: passing a null {@link Comparator} is 048 * equivalent to a Comparator with natural ordering.</li> 049 * </ul> 050 * 051 * @since 4.1 052 */ 053public class IterableUtils { 054 055 /** 056 * Inner class to distinguish unmodifiable instances. 057 */ 058 private static final class UnmodifiableIterable<E> extends FluentIterable<E> { 059 060 private final Iterable<E> iterable; 061 062 UnmodifiableIterable(final Iterable<E> iterable) { 063 this.iterable = iterable; 064 } 065 066 @Override 067 public Iterator<E> iterator() { 068 return IteratorUtils.unmodifiableIterator(iterable.iterator()); 069 } 070 } 071 072 /** 073 * An empty iterable. 074 */ 075 @SuppressWarnings("rawtypes") 076 static final FluentIterable EMPTY_ITERABLE = new FluentIterable<Object>() { 077 078 @Override 079 public Iterator<Object> iterator() { 080 return IteratorUtils.emptyIterator(); 081 } 082 }; 083 084 /** 085 * Returns a view of the given iterable that contains at most the given number of elements. 086 * <p> 087 * The returned iterable's iterator supports {@code remove()} when the corresponding input iterator supports it. 088 * </p> 089 * 090 * @param <E> The element type. 091 * @param iterable The iterable to limit, may not be null. 092 * @param maxSize The maximum number of elements, must not be negative. 093 * @return A bounded view on the specified iterable. 094 * @throws IllegalArgumentException if maxSize is negative. 095 * @throws NullPointerException if iterable is null. 096 */ 097 public static <E> Iterable<E> boundedIterable(final Iterable<E> iterable, final long maxSize) { 098 Objects.requireNonNull(iterable, "iterable"); 099 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}