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