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