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