1 /* 2 * Copyright (C) 2008 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.collect; 18 19 import static com.google.common.base.Preconditions.checkArgument; 20 import static com.google.common.base.Preconditions.checkNotNull; 21 import static com.google.common.base.Predicates.and; 22 import static com.google.common.base.Predicates.in; 23 import static com.google.common.base.Predicates.not; 24 import static com.google.common.collect.CollectPreconditions.checkNonnegative; 25 import static com.google.common.math.LongMath.binomial; 26 27 import com.google.common.annotations.Beta; 28 import com.google.common.annotations.GwtCompatible; 29 import com.google.common.base.Function; 30 import com.google.common.base.Joiner; 31 import com.google.common.base.Predicate; 32 import com.google.common.base.Predicates; 33 import com.google.common.math.IntMath; 34 import com.google.common.primitives.Ints; 35 36 import java.util.AbstractCollection; 37 import java.util.ArrayList; 38 import java.util.Arrays; 39 import java.util.Collection; 40 import java.util.Collections; 41 import java.util.Comparator; 42 import java.util.Iterator; 43 import java.util.List; 44 45 import javax.annotation.Nullable; 46 47 /** 48 * Provides static methods for working with {@code Collection} instances. 49 * 50 * @author Chris Povirk 51 * @author Mike Bostock 52 * @author Jared Levy 53 * @since 2.0 (imported from Google Collections Library) 54 */ 55 @GwtCompatible 56 public final class Collections2 { Collections2()57 private Collections2() {} 58 59 /** 60 * Returns the elements of {@code unfiltered} that satisfy a predicate. The 61 * returned collection is a live view of {@code unfiltered}; changes to one 62 * affect the other. 63 * 64 * <p>The resulting collection's iterator does not support {@code remove()}, 65 * but all other collection methods are supported. When given an element that 66 * doesn't satisfy the predicate, the collection's {@code add()} and {@code 67 * addAll()} methods throw an {@link IllegalArgumentException}. When methods 68 * such as {@code removeAll()} and {@code clear()} are called on the filtered 69 * collection, only elements that satisfy the filter will be removed from the 70 * underlying collection. 71 * 72 * <p>The returned collection isn't threadsafe or serializable, even if 73 * {@code unfiltered} is. 74 * 75 * <p>Many of the filtered collection's methods, such as {@code size()}, 76 * iterate across every element in the underlying collection and determine 77 * which elements satisfy the filter. When a live view is <i>not</i> needed, 78 * it may be faster to copy {@code Iterables.filter(unfiltered, predicate)} 79 * and use the copy. 80 * 81 * <p><b>Warning:</b> {@code predicate} must be <i>consistent with equals</i>, 82 * as documented at {@link Predicate#apply}. Do not provide a predicate such 83 * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent 84 * with equals. (See {@link Iterables#filter(Iterable, Class)} for related 85 * functionality.) 86 */ 87 // TODO(kevinb): how can we omit that Iterables link when building gwt 88 // javadoc? filter( Collection<E> unfiltered, Predicate<? super E> predicate)89 public static <E> Collection<E> filter( 90 Collection<E> unfiltered, Predicate<? super E> predicate) { 91 if (unfiltered instanceof FilteredCollection) { 92 // Support clear(), removeAll(), and retainAll() when filtering a filtered 93 // collection. 94 return ((FilteredCollection<E>) unfiltered).createCombined(predicate); 95 } 96 97 return new FilteredCollection<E>( 98 checkNotNull(unfiltered), checkNotNull(predicate)); 99 } 100 101 /** 102 * Delegates to {@link Collection#contains}. Returns {@code false} if the 103 * {@code contains} method throws a {@code ClassCastException} or 104 * {@code NullPointerException}. 105 */ safeContains( Collection<?> collection, @Nullable Object object)106 static boolean safeContains( 107 Collection<?> collection, @Nullable Object object) { 108 checkNotNull(collection); 109 try { 110 return collection.contains(object); 111 } catch (ClassCastException e) { 112 return false; 113 } catch (NullPointerException e) { 114 return false; 115 } 116 } 117 118 /** 119 * Delegates to {@link Collection#remove}. Returns {@code false} if the 120 * {@code remove} method throws a {@code ClassCastException} or 121 * {@code NullPointerException}. 122 */ safeRemove(Collection<?> collection, @Nullable Object object)123 static boolean safeRemove(Collection<?> collection, @Nullable Object object) { 124 checkNotNull(collection); 125 try { 126 return collection.remove(object); 127 } catch (ClassCastException e) { 128 return false; 129 } catch (NullPointerException e) { 130 return false; 131 } 132 } 133 134 static class FilteredCollection<E> extends AbstractCollection<E> { 135 final Collection<E> unfiltered; 136 final Predicate<? super E> predicate; 137 FilteredCollection(Collection<E> unfiltered, Predicate<? super E> predicate)138 FilteredCollection(Collection<E> unfiltered, 139 Predicate<? super E> predicate) { 140 this.unfiltered = unfiltered; 141 this.predicate = predicate; 142 } 143 createCombined(Predicate<? super E> newPredicate)144 FilteredCollection<E> createCombined(Predicate<? super E> newPredicate) { 145 return new FilteredCollection<E>(unfiltered, 146 Predicates.<E>and(predicate, newPredicate)); 147 // .<E> above needed to compile in JDK 5 148 } 149 150 @Override add(E element)151 public boolean add(E element) { 152 checkArgument(predicate.apply(element)); 153 return unfiltered.add(element); 154 } 155 156 @Override addAll(Collection<? extends E> collection)157 public boolean addAll(Collection<? extends E> collection) { 158 for (E element : collection) { 159 checkArgument(predicate.apply(element)); 160 } 161 return unfiltered.addAll(collection); 162 } 163 164 @Override clear()165 public void clear() { 166 Iterables.removeIf(unfiltered, predicate); 167 } 168 169 @Override contains(@ullable Object element)170 public boolean contains(@Nullable Object element) { 171 if (safeContains(unfiltered, element)) { 172 @SuppressWarnings("unchecked") // element is in unfiltered, so it must be an E 173 E e = (E) element; 174 return predicate.apply(e); 175 } 176 return false; 177 } 178 179 @Override containsAll(Collection<?> collection)180 public boolean containsAll(Collection<?> collection) { 181 return containsAllImpl(this, collection); 182 } 183 184 @Override isEmpty()185 public boolean isEmpty() { 186 return !Iterables.any(unfiltered, predicate); 187 } 188 189 @Override iterator()190 public Iterator<E> iterator() { 191 return Iterators.filter(unfiltered.iterator(), predicate); 192 } 193 194 @Override remove(Object element)195 public boolean remove(Object element) { 196 return contains(element) && unfiltered.remove(element); 197 } 198 199 @Override removeAll(final Collection<?> collection)200 public boolean removeAll(final Collection<?> collection) { 201 return Iterables.removeIf(unfiltered, and(predicate, Predicates.<Object>in(collection))); 202 } 203 204 @Override retainAll(final Collection<?> collection)205 public boolean retainAll(final Collection<?> collection) { 206 return Iterables.removeIf(unfiltered, and(predicate, not(Predicates.<Object>in(collection)))); 207 } 208 209 @Override size()210 public int size() { 211 return Iterators.size(iterator()); 212 } 213 214 @Override toArray()215 public Object[] toArray() { 216 // creating an ArrayList so filtering happens once 217 return Lists.newArrayList(iterator()).toArray(); 218 } 219 220 @Override toArray(T[] array)221 public <T> T[] toArray(T[] array) { 222 return Lists.newArrayList(iterator()).toArray(array); 223 } 224 } 225 226 /** 227 * Returns a collection that applies {@code function} to each element of 228 * {@code fromCollection}. The returned collection is a live view of {@code 229 * fromCollection}; changes to one affect the other. 230 * 231 * <p>The returned collection's {@code add()} and {@code addAll()} methods 232 * throw an {@link UnsupportedOperationException}. All other collection 233 * methods are supported, as long as {@code fromCollection} supports them. 234 * 235 * <p>The returned collection isn't threadsafe or serializable, even if 236 * {@code fromCollection} is. 237 * 238 * <p>When a live view is <i>not</i> needed, it may be faster to copy the 239 * transformed collection and use the copy. 240 * 241 * <p>If the input {@code Collection} is known to be a {@code List}, consider 242 * {@link Lists#transform}. If only an {@code Iterable} is available, use 243 * {@link Iterables#transform}. 244 */ transform(Collection<F> fromCollection, Function<? super F, T> function)245 public static <F, T> Collection<T> transform(Collection<F> fromCollection, 246 Function<? super F, T> function) { 247 return new TransformedCollection<F, T>(fromCollection, function); 248 } 249 250 static class TransformedCollection<F, T> extends AbstractCollection<T> { 251 final Collection<F> fromCollection; 252 final Function<? super F, ? extends T> function; 253 TransformedCollection(Collection<F> fromCollection, Function<? super F, ? extends T> function)254 TransformedCollection(Collection<F> fromCollection, 255 Function<? super F, ? extends T> function) { 256 this.fromCollection = checkNotNull(fromCollection); 257 this.function = checkNotNull(function); 258 } 259 clear()260 @Override public void clear() { 261 fromCollection.clear(); 262 } 263 isEmpty()264 @Override public boolean isEmpty() { 265 return fromCollection.isEmpty(); 266 } 267 iterator()268 @Override public Iterator<T> iterator() { 269 return Iterators.transform(fromCollection.iterator(), function); 270 } 271 size()272 @Override public int size() { 273 return fromCollection.size(); 274 } 275 } 276 277 /** 278 * Returns {@code true} if the collection {@code self} contains all of the 279 * elements in the collection {@code c}. 280 * 281 * <p>This method iterates over the specified collection {@code c}, checking 282 * each element returned by the iterator in turn to see if it is contained in 283 * the specified collection {@code self}. If all elements are so contained, 284 * {@code true} is returned, otherwise {@code false}. 285 * 286 * @param self a collection which might contain all elements in {@code c} 287 * @param c a collection whose elements might be contained by {@code self} 288 */ containsAllImpl(Collection<?> self, Collection<?> c)289 static boolean containsAllImpl(Collection<?> self, Collection<?> c) { 290 return Iterables.all(c, Predicates.in(self)); 291 } 292 293 /** 294 * An implementation of {@link Collection#toString()}. 295 */ toStringImpl(final Collection<?> collection)296 static String toStringImpl(final Collection<?> collection) { 297 StringBuilder sb 298 = newStringBuilderForCollection(collection.size()).append('['); 299 STANDARD_JOINER.appendTo( 300 sb, Iterables.transform(collection, new Function<Object, Object>() { 301 @Override public Object apply(Object input) { 302 return input == collection ? "(this Collection)" : input; 303 } 304 })); 305 return sb.append(']').toString(); 306 } 307 308 /** 309 * Returns best-effort-sized StringBuilder based on the given collection size. 310 */ newStringBuilderForCollection(int size)311 static StringBuilder newStringBuilderForCollection(int size) { 312 checkNonnegative(size, "size"); 313 return new StringBuilder((int) Math.min(size * 8L, Ints.MAX_POWER_OF_TWO)); 314 } 315 316 /** 317 * Used to avoid http://bugs.sun.com/view_bug.do?bug_id=6558557 318 */ cast(Iterable<T> iterable)319 static <T> Collection<T> cast(Iterable<T> iterable) { 320 return (Collection<T>) iterable; 321 } 322 323 static final Joiner STANDARD_JOINER = Joiner.on(", ").useForNull("null"); 324 325 /** 326 * Returns a {@link Collection} of all the permutations of the specified 327 * {@link Iterable}. 328 * 329 * <p><i>Notes:</i> This is an implementation of the algorithm for 330 * Lexicographical Permutations Generation, described in Knuth's "The Art of 331 * Computer Programming", Volume 4, Chapter 7, Section 7.2.1.2. The 332 * iteration order follows the lexicographical order. This means that 333 * the first permutation will be in ascending order, and the last will be in 334 * descending order. 335 * 336 * <p>Duplicate elements are considered equal. For example, the list [1, 1] 337 * will have only one permutation, instead of two. This is why the elements 338 * have to implement {@link Comparable}. 339 * 340 * <p>An empty iterable has only one permutation, which is an empty list. 341 * 342 * <p>This method is equivalent to 343 * {@code Collections2.orderedPermutations(list, Ordering.natural())}. 344 * 345 * @param elements the original iterable whose elements have to be permuted. 346 * @return an immutable {@link Collection} containing all the different 347 * permutations of the original iterable. 348 * @throws NullPointerException if the specified iterable is null or has any 349 * null elements. 350 * @since 12.0 351 */ 352 @Beta public static <E extends Comparable<? super E>> orderedPermutations(Iterable<E> elements)353 Collection<List<E>> orderedPermutations(Iterable<E> elements) { 354 return orderedPermutations(elements, Ordering.natural()); 355 } 356 357 /** 358 * Returns a {@link Collection} of all the permutations of the specified 359 * {@link Iterable} using the specified {@link Comparator} for establishing 360 * the lexicographical ordering. 361 * 362 * <p>Examples: <pre> {@code 363 * 364 * for (List<String> perm : orderedPermutations(asList("b", "c", "a"))) { 365 * println(perm); 366 * } 367 * // -> ["a", "b", "c"] 368 * // -> ["a", "c", "b"] 369 * // -> ["b", "a", "c"] 370 * // -> ["b", "c", "a"] 371 * // -> ["c", "a", "b"] 372 * // -> ["c", "b", "a"] 373 * 374 * for (List<Integer> perm : orderedPermutations(asList(1, 2, 2, 1))) { 375 * println(perm); 376 * } 377 * // -> [1, 1, 2, 2] 378 * // -> [1, 2, 1, 2] 379 * // -> [1, 2, 2, 1] 380 * // -> [2, 1, 1, 2] 381 * // -> [2, 1, 2, 1] 382 * // -> [2, 2, 1, 1]}</pre> 383 * 384 * <p><i>Notes:</i> This is an implementation of the algorithm for 385 * Lexicographical Permutations Generation, described in Knuth's "The Art of 386 * Computer Programming", Volume 4, Chapter 7, Section 7.2.1.2. The 387 * iteration order follows the lexicographical order. This means that 388 * the first permutation will be in ascending order, and the last will be in 389 * descending order. 390 * 391 * <p>Elements that compare equal are considered equal and no new permutations 392 * are created by swapping them. 393 * 394 * <p>An empty iterable has only one permutation, which is an empty list. 395 * 396 * @param elements the original iterable whose elements have to be permuted. 397 * @param comparator a comparator for the iterable's elements. 398 * @return an immutable {@link Collection} containing all the different 399 * permutations of the original iterable. 400 * @throws NullPointerException If the specified iterable is null, has any 401 * null elements, or if the specified comparator is null. 402 * @since 12.0 403 */ orderedPermutations( Iterable<E> elements, Comparator<? super E> comparator)404 @Beta public static <E> Collection<List<E>> orderedPermutations( 405 Iterable<E> elements, Comparator<? super E> comparator) { 406 return new OrderedPermutationCollection<E>(elements, comparator); 407 } 408 409 private static final class OrderedPermutationCollection<E> 410 extends AbstractCollection<List<E>> { 411 final ImmutableList<E> inputList; 412 final Comparator<? super E> comparator; 413 final int size; 414 OrderedPermutationCollection(Iterable<E> input, Comparator<? super E> comparator)415 OrderedPermutationCollection(Iterable<E> input, 416 Comparator<? super E> comparator) { 417 this.inputList = Ordering.from(comparator).immutableSortedCopy(input); 418 this.comparator = comparator; 419 this.size = calculateSize(inputList, comparator); 420 } 421 422 /** 423 * The number of permutations with repeated elements is calculated as 424 * follows: 425 * <ul> 426 * <li>For an empty list, it is 1 (base case).</li> 427 * <li>When r numbers are added to a list of n-r elements, the number of 428 * permutations is increased by a factor of (n choose r).</li> 429 * </ul> 430 */ calculateSize( List<E> sortedInputList, Comparator<? super E> comparator)431 private static <E> int calculateSize( 432 List<E> sortedInputList, Comparator<? super E> comparator) { 433 long permutations = 1; 434 int n = 1; 435 int r = 1; 436 while (n < sortedInputList.size()) { 437 int comparison = comparator.compare( 438 sortedInputList.get(n - 1), sortedInputList.get(n)); 439 if (comparison < 0) { 440 // We move to the next non-repeated element. 441 permutations *= binomial(n, r); 442 r = 0; 443 if (!isPositiveInt(permutations)) { 444 return Integer.MAX_VALUE; 445 } 446 } 447 n++; 448 r++; 449 } 450 permutations *= binomial(n, r); 451 if (!isPositiveInt(permutations)) { 452 return Integer.MAX_VALUE; 453 } 454 return (int) permutations; 455 } 456 size()457 @Override public int size() { 458 return size; 459 } 460 isEmpty()461 @Override public boolean isEmpty() { 462 return false; 463 } 464 iterator()465 @Override public Iterator<List<E>> iterator() { 466 return new OrderedPermutationIterator<E>(inputList, comparator); 467 } 468 contains(@ullable Object obj)469 @Override public boolean contains(@Nullable Object obj) { 470 if (obj instanceof List) { 471 List<?> list = (List<?>) obj; 472 return isPermutation(inputList, list); 473 } 474 return false; 475 } 476 toString()477 @Override public String toString() { 478 return "orderedPermutationCollection(" + inputList + ")"; 479 } 480 } 481 482 private static final class OrderedPermutationIterator<E> 483 extends AbstractIterator<List<E>> { 484 485 List<E> nextPermutation; 486 final Comparator<? super E> comparator; 487 OrderedPermutationIterator(List<E> list, Comparator<? super E> comparator)488 OrderedPermutationIterator(List<E> list, 489 Comparator<? super E> comparator) { 490 this.nextPermutation = Lists.newArrayList(list); 491 this.comparator = comparator; 492 } 493 computeNext()494 @Override protected 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 calculateNextPermutation()503 void calculateNextPermutation() { 504 int j = findNextJ(); 505 if (j == -1) { 506 nextPermutation = null; 507 return; 508 } 509 510 int l = findNextL(j); 511 Collections.swap(nextPermutation, j, l); 512 int n = nextPermutation.size(); 513 Collections.reverse(nextPermutation.subList(j + 1, n)); 514 } 515 findNextJ()516 int findNextJ() { 517 for (int k = nextPermutation.size() - 2; k >= 0; k--) { 518 if (comparator.compare(nextPermutation.get(k), 519 nextPermutation.get(k + 1)) < 0) { 520 return k; 521 } 522 } 523 return -1; 524 } 525 findNextL(int j)526 int findNextL(int j) { 527 E ak = nextPermutation.get(j); 528 for (int l = nextPermutation.size() - 1; l > j; l--) { 529 if (comparator.compare(ak, nextPermutation.get(l)) < 0) { 530 return l; 531 } 532 } 533 throw new AssertionError("this statement should be unreachable"); 534 } 535 } 536 537 /** 538 * Returns a {@link Collection} of all the permutations of the specified 539 * {@link Collection}. 540 * 541 * <p><i>Notes:</i> This is an implementation of the Plain Changes algorithm 542 * for permutations generation, described in Knuth's "The Art of Computer 543 * Programming", Volume 4, Chapter 7, Section 7.2.1.2. 544 * 545 * <p>If the input list contains equal elements, some of the generated 546 * permutations will be equal. 547 * 548 * <p>An empty collection has only one permutation, which is an empty list. 549 * 550 * @param elements the original collection whose elements have to be permuted. 551 * @return an immutable {@link Collection} containing all the different 552 * permutations of the original collection. 553 * @throws NullPointerException if the specified collection is null or has any 554 * null elements. 555 * @since 12.0 556 */ permutations( Collection<E> elements)557 @Beta public static <E> Collection<List<E>> permutations( 558 Collection<E> elements) { 559 return new PermutationCollection<E>(ImmutableList.copyOf(elements)); 560 } 561 562 private static final class PermutationCollection<E> 563 extends AbstractCollection<List<E>> { 564 final ImmutableList<E> inputList; 565 PermutationCollection(ImmutableList<E> input)566 PermutationCollection(ImmutableList<E> input) { 567 this.inputList = input; 568 } 569 size()570 @Override public int size() { 571 return IntMath.factorial(inputList.size()); 572 } 573 isEmpty()574 @Override public boolean isEmpty() { 575 return false; 576 } 577 iterator()578 @Override public Iterator<List<E>> iterator() { 579 return new PermutationIterator<E>(inputList); 580 } 581 contains(@ullable Object obj)582 @Override public boolean contains(@Nullable Object obj) { 583 if (obj instanceof List) { 584 List<?> list = (List<?>) obj; 585 return isPermutation(inputList, list); 586 } 587 return false; 588 } 589 toString()590 @Override public String toString() { 591 return "permutations(" + inputList + ")"; 592 } 593 } 594 595 private static class PermutationIterator<E> 596 extends AbstractIterator<List<E>> { 597 final List<E> list; 598 final int[] c; 599 final int[] o; 600 int j; 601 PermutationIterator(List<E> list)602 PermutationIterator(List<E> list) { 603 this.list = new ArrayList<E>(list); 604 int n = list.size(); 605 c = new int[n]; 606 o = new int[n]; 607 Arrays.fill(c, 0); 608 Arrays.fill(o, 1); 609 j = Integer.MAX_VALUE; 610 } 611 computeNext()612 @Override protected List<E> computeNext() { 613 if (j <= 0) { 614 return endOfData(); 615 } 616 ImmutableList<E> next = ImmutableList.copyOf(list); 617 calculateNextPermutation(); 618 return next; 619 } 620 calculateNextPermutation()621 void calculateNextPermutation() { 622 j = list.size() - 1; 623 int s = 0; 624 625 // Handle the special case of an empty list. Skip the calculation of the 626 // next permutation. 627 if (j == -1) { 628 return; 629 } 630 631 while (true) { 632 int q = c[j] + o[j]; 633 if (q < 0) { 634 switchDirection(); 635 continue; 636 } 637 if (q == j + 1) { 638 if (j == 0) { 639 break; 640 } 641 s++; 642 switchDirection(); 643 continue; 644 } 645 646 Collections.swap(list, j - c[j] + s, j - q + s); 647 c[j] = q; 648 break; 649 } 650 } 651 switchDirection()652 void switchDirection() { 653 o[j] = -o[j]; 654 j--; 655 } 656 } 657 658 /** 659 * Returns {@code true} if the second list is a permutation of the first. 660 */ isPermutation(List<?> first, List<?> second)661 private static boolean isPermutation(List<?> first, 662 List<?> second) { 663 if (first.size() != second.size()) { 664 return false; 665 } 666 Multiset<?> firstMultiset = HashMultiset.create(first); 667 Multiset<?> secondMultiset = HashMultiset.create(second); 668 return firstMultiset.equals(secondMultiset); 669 } 670 isPositiveInt(long n)671 private static boolean isPositiveInt(long n) { 672 return n >= 0 && n <= Integer.MAX_VALUE; 673 } 674 } 675