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