001/* 002 * Copyright (C) 2008 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.google.common.collect; 018 019import static com.google.common.base.Preconditions.checkArgument; 020import static com.google.common.base.Preconditions.checkNotNull; 021import static com.google.common.base.Predicates.and; 022import static com.google.common.collect.CollectPreconditions.checkNonnegative; 023import static com.google.common.collect.Iterables.any; 024import static com.google.common.collect.Lists.newArrayList; 025import static java.lang.Math.min; 026import static java.util.Objects.requireNonNull; 027 028import com.google.common.annotations.GwtCompatible; 029import com.google.common.annotations.GwtIncompatible; 030import com.google.common.base.Function; 031import com.google.common.base.Predicate; 032import com.google.common.math.IntMath; 033import com.google.common.primitives.Ints; 034import java.util.AbstractCollection; 035import java.util.ArrayList; 036import java.util.Arrays; 037import java.util.Collection; 038import java.util.Collections; 039import java.util.Comparator; 040import java.util.Iterator; 041import java.util.List; 042import java.util.Spliterator; 043import java.util.function.Consumer; 044import org.jspecify.annotations.Nullable; 045 046/** 047 * Provides static methods for working with {@code Collection} instances. 048 * 049 * <p><b>Java 8+ users:</b> several common uses for this class are now more comprehensively 050 * addressed by the new {@link java.util.stream.Stream} library. Read the method documentation below 051 * for comparisons. These methods are not being deprecated, but we gently encourage you to migrate 052 * to streams. 053 * 054 * @author Chris Povirk 055 * @author Mike Bostock 056 * @author Jared Levy 057 * @since 2.0 058 */ 059@GwtCompatible 060public final class Collections2 { 061 private Collections2() {} 062 063 /** 064 * Returns the elements of {@code unfiltered} that satisfy a predicate. The returned collection is 065 * a live view of {@code unfiltered}; changes to one affect the other. 066 * 067 * <p>The resulting collection's iterator does not support {@code remove()}, but all other 068 * collection methods are supported. When given an element that doesn't satisfy the predicate, the 069 * collection's {@code add()} and {@code addAll()} methods throw an {@link 070 * IllegalArgumentException}. When methods such as {@code removeAll()} and {@code clear()} are 071 * called on the filtered collection, only elements that satisfy the filter will be removed from 072 * the underlying collection. 073 * 074 * <p>The returned collection isn't threadsafe or serializable, even if {@code unfiltered} is. 075 * 076 * <p>Many of the filtered collection's methods, such as {@code size()}, iterate across every 077 * element in the underlying collection and determine which elements satisfy the filter. When a 078 * live view is <i>not</i> needed, it may be faster to copy {@code Iterables.filter(unfiltered, 079 * predicate)} and use the copy. 080 * 081 * <p><b>Warning:</b> {@code predicate} must be <i>consistent with equals</i>, as documented at 082 * {@link Predicate#apply}. Do not provide a predicate such as {@code 083 * Predicates.instanceOf(ArrayList.class)}, which is inconsistent with equals. (See {@link 084 * Iterables#filter(Iterable, Class)} for related functionality.) 085 * 086 * <p><b>{@code Stream} equivalent:</b> {@link java.util.stream.Stream#filter Stream.filter}. 087 */ 088 public static <E extends @Nullable Object> Collection<E> filter( 089 Collection<E> unfiltered, Predicate<? super E> predicate) { 090 if (unfiltered instanceof FilteredCollection) { 091 // Support clear(), removeAll(), and retainAll() when filtering a filtered 092 // collection. 093 return ((FilteredCollection<E>) unfiltered).createCombined(predicate); 094 } 095 096 return new FilteredCollection<>(checkNotNull(unfiltered), checkNotNull(predicate)); 097 } 098 099 /** 100 * Delegates to {@link Collection#contains}. Returns {@code false} if the {@code contains} method 101 * throws a {@code ClassCastException} or {@code NullPointerException}. 102 */ 103 static boolean safeContains(Collection<?> collection, @Nullable Object object) { 104 checkNotNull(collection); 105 try { 106 return collection.contains(object); 107 } catch (ClassCastException | NullPointerException e) { 108 return false; 109 } 110 } 111 112 /** 113 * Delegates to {@link Collection#remove}. Returns {@code false} if the {@code remove} method 114 * throws a {@code ClassCastException} or {@code NullPointerException}. 115 */ 116 static boolean safeRemove(Collection<?> collection, @Nullable Object object) { 117 checkNotNull(collection); 118 try { 119 return collection.remove(object); 120 } catch (ClassCastException | NullPointerException e) { 121 return false; 122 } 123 } 124 125 static class FilteredCollection<E extends @Nullable Object> extends AbstractCollection<E> { 126 final Collection<E> unfiltered; 127 final Predicate<? super E> predicate; 128 129 FilteredCollection(Collection<E> unfiltered, Predicate<? super E> predicate) { 130 this.unfiltered = unfiltered; 131 this.predicate = predicate; 132 } 133 134 FilteredCollection<E> createCombined(Predicate<? super E> newPredicate) { 135 return new FilteredCollection<>(unfiltered, and(predicate, newPredicate)); 136 } 137 138 @Override 139 public boolean add(@ParametricNullness E element) { 140 checkArgument(predicate.apply(element)); 141 return unfiltered.add(element); 142 } 143 144 @Override 145 public boolean addAll(Collection<? extends E> collection) { 146 for (E element : collection) { 147 checkArgument(predicate.apply(element)); 148 } 149 return unfiltered.addAll(collection); 150 } 151 152 @Override 153 public void clear() { 154 Iterables.removeIf(unfiltered, predicate); 155 } 156 157 @Override 158 public boolean contains(@Nullable Object element) { 159 if (safeContains(unfiltered, element)) { 160 @SuppressWarnings("unchecked") // element is in unfiltered, so it must be an E 161 E e = (E) element; 162 return predicate.apply(e); 163 } 164 return false; 165 } 166 167 @Override 168 public boolean containsAll(Collection<?> collection) { 169 return containsAllImpl(this, collection); 170 } 171 172 @Override 173 public boolean isEmpty() { 174 return !any(unfiltered, predicate); 175 } 176 177 @Override 178 public Iterator<E> iterator() { 179 return Iterators.filter(unfiltered.iterator(), predicate); 180 } 181 182 @Override 183 @GwtIncompatible // Spliterator 184 public Spliterator<E> spliterator() { 185 return CollectSpliterators.filter(unfiltered.spliterator(), predicate); 186 } 187 188 @Override 189 public void forEach(Consumer<? super E> action) { 190 checkNotNull(action); 191 unfiltered.forEach( 192 (E e) -> { 193 if (predicate.test(e)) { 194 action.accept(e); 195 } 196 }); 197 } 198 199 @Override 200 public boolean remove(@Nullable Object element) { 201 return contains(element) && unfiltered.remove(element); 202 } 203 204 @Override 205 public boolean removeAll(Collection<?> collection) { 206 return removeIf(collection::contains); 207 } 208 209 @Override 210 public boolean retainAll(Collection<?> collection) { 211 return removeIf(element -> !collection.contains(element)); 212 } 213 214 @Override 215 public boolean removeIf(java.util.function.Predicate<? super E> filter) { 216 checkNotNull(filter); 217 return unfiltered.removeIf(element -> predicate.apply(element) && filter.test(element)); 218 } 219 220 @Override 221 public int size() { 222 int size = 0; 223 for (E e : unfiltered) { 224 if (predicate.apply(e)) { 225 size++; 226 } 227 } 228 return size; 229 } 230 231 @Override 232 public @Nullable Object[] toArray() { 233 // creating an ArrayList so filtering happens once 234 return newArrayList(iterator()).toArray(); 235 } 236 237 @Override 238 @SuppressWarnings("nullness") // b/192354773 in our checker affects toArray declarations 239 public <T extends @Nullable Object> T[] toArray(T[] array) { 240 return newArrayList(iterator()).toArray(array); 241 } 242 } 243 244 /** 245 * Returns a collection that applies {@code function} to each element of {@code fromCollection}. 246 * The returned collection is a live view of {@code fromCollection}; changes to one affect the 247 * other. 248 * 249 * <p>The returned collection's {@code add()} and {@code addAll()} methods throw an {@link 250 * UnsupportedOperationException}. All other collection methods are supported, as long as {@code 251 * fromCollection} supports them. 252 * 253 * <p>The returned collection isn't threadsafe or serializable, even if {@code fromCollection} is. 254 * 255 * <p>When a live view is <i>not</i> needed, it may be faster to copy the transformed collection 256 * and use the copy. 257 * 258 * <p>If the input {@code Collection} is known to be a {@code List}, consider {@link 259 * Lists#transform}. If only an {@code Iterable} is available, use {@link Iterables#transform}. 260 * 261 * <p><b>{@code Stream} equivalent:</b> {@link java.util.stream.Stream#map Stream.map}. 262 */ 263 public static <F extends @Nullable Object, T extends @Nullable Object> Collection<T> transform( 264 Collection<F> fromCollection, Function<? super F, T> function) { 265 return new TransformedCollection<>(fromCollection, function); 266 } 267 268 private static final class TransformedCollection< 269 F extends @Nullable Object, T extends @Nullable Object> 270 extends AbstractCollection<T> { 271 final Collection<F> fromCollection; 272 final Function<? super F, ? extends T> function; 273 274 TransformedCollection(Collection<F> fromCollection, Function<? super F, ? extends T> function) { 275 this.fromCollection = checkNotNull(fromCollection); 276 this.function = checkNotNull(function); 277 } 278 279 @Override 280 public void clear() { 281 fromCollection.clear(); 282 } 283 284 @Override 285 public boolean isEmpty() { 286 return fromCollection.isEmpty(); 287 } 288 289 @Override 290 public Iterator<T> iterator() { 291 return Iterators.transform(fromCollection.iterator(), function); 292 } 293 294 @Override 295 @GwtIncompatible // Spliterator 296 public Spliterator<T> spliterator() { 297 return CollectSpliterators.map(fromCollection.spliterator(), 0, function); 298 } 299 300 @Override 301 public void forEach(Consumer<? super T> action) { 302 checkNotNull(action); 303 fromCollection.forEach((F f) -> action.accept(function.apply(f))); 304 } 305 306 @Override 307 public boolean removeIf(java.util.function.Predicate<? super T> filter) { 308 checkNotNull(filter); 309 return fromCollection.removeIf(element -> filter.test(function.apply(element))); 310 } 311 312 @Override 313 public int size() { 314 return fromCollection.size(); 315 } 316 } 317 318 /** 319 * Returns {@code true} if the collection {@code self} contains all of the elements in the 320 * collection {@code c}. 321 * 322 * <p>This method iterates over the specified collection {@code c}, checking each element returned 323 * by the iterator in turn to see if it is contained in the specified collection {@code self}. If 324 * all elements are so contained, {@code true} is returned, otherwise {@code false}. 325 * 326 * @param self a collection which might contain all elements in {@code c} 327 * @param c a collection whose elements might be contained by {@code self} 328 */ 329 static boolean containsAllImpl(Collection<?> self, Collection<?> c) { 330 for (Object o : c) { 331 if (!self.contains(o)) { 332 return false; 333 } 334 } 335 return true; 336 } 337 338 /** An implementation of {@code Collection.toString()}. */ 339 @SuppressWarnings("ReferenceEquality") // using == to detect direct infinite recursion 340 static String toStringImpl(Collection<?> collection) { 341 StringBuilder sb = newStringBuilderForCollection(collection.size()).append('['); 342 boolean first = true; 343 for (Object o : collection) { 344 if (!first) { 345 sb.append(", "); 346 } 347 first = false; 348 if (o == collection) { 349 sb.append("(this Collection)"); 350 } else { 351 sb.append(o); 352 } 353 } 354 return sb.append(']').toString(); 355 } 356 357 /** Returns best-effort-sized StringBuilder based on the given collection size. */ 358 static StringBuilder newStringBuilderForCollection(int size) { 359 checkNonnegative(size, "size"); 360 return new StringBuilder((int) min(size * 8L, Ints.MAX_POWER_OF_TWO)); 361 } 362 363 /** 364 * Returns a {@link Collection} of all the permutations of the specified {@link Iterable}. 365 * 366 * <p><i>Notes:</i> This is an implementation of the algorithm for Lexicographical Permutations 367 * Generation, described in Knuth's "The Art of Computer Programming", Volume 4, Chapter 7, 368 * Section 7.2.1.2. The iteration order follows the lexicographical order. This means that the 369 * first permutation will be in ascending order, and the last will be in descending order. 370 * 371 * <p>Duplicate elements are considered equal. For example, the list [1, 1] will have only one 372 * permutation, instead of two. This is why the elements have to implement {@link Comparable}. 373 * 374 * <p>An empty iterable has only one permutation, which is an empty list. 375 * 376 * <p>This method is equivalent to {@code Collections2.orderedPermutations(list, 377 * Ordering.natural())}. 378 * 379 * @param elements the original iterable whose elements have to be permuted. 380 * @return an immutable {@link Collection} containing all the different permutations of the 381 * original iterable. 382 * @throws NullPointerException if the specified iterable is null or has any null elements. 383 * @since 12.0 384 */ 385 public static <E extends Comparable<? super E>> Collection<List<E>> orderedPermutations( 386 Iterable<E> elements) { 387 return orderedPermutations(elements, Ordering.natural()); 388 } 389 390 /** 391 * Returns a {@link Collection} of all the permutations of the specified {@link Iterable} using 392 * the specified {@link Comparator} for establishing the lexicographical ordering. 393 * 394 * <p>Examples: 395 * 396 * {@snippet : 397 * for (List<String> perm : orderedPermutations(asList("b", "c", "a"))) { 398 * println(perm); 399 * } 400 * // -> ["a", "b", "c"] 401 * // -> ["a", "c", "b"] 402 * // -> ["b", "a", "c"] 403 * // -> ["b", "c", "a"] 404 * // -> ["c", "a", "b"] 405 * // -> ["c", "b", "a"] 406 * 407 * for (List<Integer> perm : orderedPermutations(asList(1, 2, 2, 1))) { 408 * println(perm); 409 * } 410 * // -> [1, 1, 2, 2] 411 * // -> [1, 2, 1, 2] 412 * // -> [1, 2, 2, 1] 413 * // -> [2, 1, 1, 2] 414 * // -> [2, 1, 2, 1] 415 * // -> [2, 2, 1, 1] 416 * } 417 * 418 * <p><i>Notes:</i> This is an implementation of the algorithm for Lexicographical Permutations 419 * Generation, described in Knuth's "The Art of Computer Programming", Volume 4, Chapter 7, 420 * Section 7.2.1.2. The iteration order follows the lexicographical order. This means that the 421 * first permutation will be in ascending order, and the last will be in descending order. 422 * 423 * <p>Elements that compare equal are considered equal and no new permutations are created by 424 * swapping them. 425 * 426 * <p>An empty iterable has only one permutation, which is an empty list. 427 * 428 * @param elements the original iterable whose elements have to be permuted. 429 * @param comparator a comparator for the iterable's elements. 430 * @return an immutable {@link Collection} containing all the different permutations of the 431 * original iterable. 432 * @throws NullPointerException If the specified iterable is null, has any null elements, or if 433 * the specified comparator is null. 434 * @since 12.0 435 */ 436 public static <E> Collection<List<E>> orderedPermutations( 437 Iterable<E> elements, Comparator<? super E> comparator) { 438 return new OrderedPermutationCollection<E>(elements, comparator); 439 } 440 441 private static final class OrderedPermutationCollection<E> extends AbstractCollection<List<E>> { 442 final ImmutableList<E> inputList; 443 final Comparator<? super E> comparator; 444 final int size; 445 446 OrderedPermutationCollection(Iterable<E> input, Comparator<? super E> comparator) { 447 this.inputList = ImmutableList.sortedCopyOf(comparator, input); 448 this.comparator = comparator; 449 this.size = calculateSize(inputList, comparator); 450 } 451 452 /** 453 * The number of permutations with repeated elements is calculated as follows: 454 * 455 * <ul> 456 * <li>For an empty list, it is 1 (base case). 457 * <li>When r numbers are added to a list of n-r elements, the number of permutations is 458 * increased by a factor of (n choose r). 459 * </ul> 460 */ 461 private static <E> int calculateSize( 462 List<E> sortedInputList, Comparator<? super E> comparator) { 463 int permutations = 1; 464 int n = 1; 465 int r = 1; 466 while (n < sortedInputList.size()) { 467 int comparison = comparator.compare(sortedInputList.get(n - 1), sortedInputList.get(n)); 468 if (comparison < 0) { 469 // We move to the next non-repeated element. 470 permutations = IntMath.saturatedMultiply(permutations, IntMath.binomial(n, r)); 471 r = 0; 472 if (permutations == Integer.MAX_VALUE) { 473 return Integer.MAX_VALUE; 474 } 475 } 476 n++; 477 r++; 478 } 479 return IntMath.saturatedMultiply(permutations, IntMath.binomial(n, r)); 480 } 481 482 @Override 483 public int size() { 484 return size; 485 } 486 487 @Override 488 public boolean isEmpty() { 489 return false; 490 } 491 492 @Override 493 public Iterator<List<E>> iterator() { 494 return new OrderedPermutationIterator<E>(inputList, comparator); 495 } 496 497 @Override 498 public boolean contains(@Nullable Object obj) { 499 if (obj instanceof List) { 500 List<?> list = (List<?>) obj; 501 return isPermutation(inputList, list); 502 } 503 return false; 504 } 505 506 @Override 507 public String toString() { 508 return "orderedPermutationCollection(" + inputList + ")"; 509 } 510 } 511 512 private static final class OrderedPermutationIterator<E> extends AbstractIterator<List<E>> { 513 @Nullable List<E> nextPermutation; 514 final Comparator<? super E> comparator; 515 516 OrderedPermutationIterator(List<E> list, Comparator<? super E> comparator) { 517 this.nextPermutation = new ArrayList<>(list); 518 this.comparator = comparator; 519 } 520 521 @Override 522 protected @Nullable List<E> computeNext() { 523 if (nextPermutation == null) { 524 return endOfData(); 525 } 526 ImmutableList<E> next = ImmutableList.copyOf(nextPermutation); 527 calculateNextPermutation(); 528 return next; 529 } 530 531 void calculateNextPermutation() { 532 int j = findNextJ(); 533 if (j == -1) { 534 nextPermutation = null; 535 return; 536 } 537 /* 538 * requireNonNull is safe because we don't clear nextPermutation until we're done calling this 539 * method. 540 */ 541 requireNonNull(nextPermutation); 542 543 int l = findNextL(j); 544 Collections.swap(nextPermutation, j, l); 545 int n = nextPermutation.size(); 546 Collections.reverse(nextPermutation.subList(j + 1, n)); 547 } 548 549 int findNextJ() { 550 /* 551 * requireNonNull is safe because we don't clear nextPermutation until we're done calling this 552 * method. 553 */ 554 requireNonNull(nextPermutation); 555 for (int k = nextPermutation.size() - 2; k >= 0; k--) { 556 if (comparator.compare(nextPermutation.get(k), nextPermutation.get(k + 1)) < 0) { 557 return k; 558 } 559 } 560 return -1; 561 } 562 563 int findNextL(int j) { 564 /* 565 * requireNonNull is safe because we don't clear nextPermutation until we're done calling this 566 * method. 567 */ 568 requireNonNull(nextPermutation); 569 E ak = nextPermutation.get(j); 570 for (int l = nextPermutation.size() - 1; l > j; l--) { 571 if (comparator.compare(ak, nextPermutation.get(l)) < 0) { 572 return l; 573 } 574 } 575 throw new AssertionError("this statement should be unreachable"); 576 } 577 } 578 579 /** 580 * Returns a {@link Collection} of all the permutations of the specified {@link Collection}. 581 * 582 * <p><i>Notes:</i> This is an implementation of the Plain Changes algorithm for permutations 583 * generation, described in Knuth's "The Art of Computer Programming", Volume 4, Chapter 7, 584 * Section 7.2.1.2. 585 * 586 * <p>If the input list contains equal elements, some of the generated permutations will be equal. 587 * 588 * <p>An empty collection has only one permutation, which is an empty list. 589 * 590 * @param elements the original collection whose elements have to be permuted. 591 * @return an immutable {@link Collection} containing all the different permutations of the 592 * original collection. 593 * @throws NullPointerException if the specified collection is null or has any null elements. 594 * @since 12.0 595 */ 596 public static <E> Collection<List<E>> permutations(Collection<E> elements) { 597 return new PermutationCollection<E>(ImmutableList.copyOf(elements)); 598 } 599 600 private static final class PermutationCollection<E> extends AbstractCollection<List<E>> { 601 final ImmutableList<E> inputList; 602 603 PermutationCollection(ImmutableList<E> input) { 604 this.inputList = input; 605 } 606 607 @Override 608 public int size() { 609 return IntMath.factorial(inputList.size()); 610 } 611 612 @Override 613 public boolean isEmpty() { 614 return false; 615 } 616 617 @Override 618 public Iterator<List<E>> iterator() { 619 return new PermutationIterator<E>(inputList); 620 } 621 622 @Override 623 public boolean contains(@Nullable Object obj) { 624 if (obj instanceof List) { 625 List<?> list = (List<?>) obj; 626 return isPermutation(inputList, list); 627 } 628 return false; 629 } 630 631 @Override 632 public String toString() { 633 return "permutations(" + inputList + ")"; 634 } 635 } 636 637 private static final class PermutationIterator<E> extends AbstractIterator<List<E>> { 638 final List<E> list; 639 final int[] c; 640 final int[] o; 641 int j; 642 643 PermutationIterator(List<E> list) { 644 this.list = new ArrayList<>(list); 645 int n = list.size(); 646 c = new int[n]; 647 o = new int[n]; 648 Arrays.fill(c, 0); 649 Arrays.fill(o, 1); 650 j = Integer.MAX_VALUE; 651 } 652 653 @Override 654 protected @Nullable List<E> computeNext() { 655 if (j <= 0) { 656 return endOfData(); 657 } 658 ImmutableList<E> next = ImmutableList.copyOf(list); 659 calculateNextPermutation(); 660 return next; 661 } 662 663 void calculateNextPermutation() { 664 j = list.size() - 1; 665 int s = 0; 666 667 // Handle the special case of an empty list. Skip the calculation of the 668 // next permutation. 669 if (j == -1) { 670 return; 671 } 672 673 while (true) { 674 int q = c[j] + o[j]; 675 if (q < 0) { 676 switchDirection(); 677 continue; 678 } 679 if (q == j + 1) { 680 if (j == 0) { 681 break; 682 } 683 s++; 684 switchDirection(); 685 continue; 686 } 687 688 Collections.swap(list, j - c[j] + s, j - q + s); 689 c[j] = q; 690 break; 691 } 692 } 693 694 void switchDirection() { 695 o[j] = -o[j]; 696 j--; 697 } 698 } 699 700 /** Returns {@code true} if the second list is a permutation of the first. */ 701 private static boolean isPermutation(List<?> first, List<?> second) { 702 if (first.size() != second.size()) { 703 return false; 704 } 705 Multiset<?> firstMultiset = HashMultiset.create(first); 706 Multiset<?> secondMultiset = HashMultiset.create(second); 707 return firstMultiset.equals(secondMultiset); 708 } 709}