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