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