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.Nullable; 046 047/** 048 * Provides static methods for working with {@code Collection} instances. 049 * 050 * @author Chris Povirk 051 * @author Mike Bostock 052 * @author Jared Levy 053 * @since 2.0 (imported from Google Collections Library) 054 */ 055@GwtCompatible 056public final class Collections2 { 057 private Collections2() {} 058 059 /** 060 * Returns the elements of {@code unfiltered} that satisfy a predicate. The 061 * returned collection is a live view of {@code unfiltered}; changes to one 062 * affect the other. 063 * 064 * <p>The resulting collection's iterator does not support {@code remove()}, 065 * but all other collection methods are supported. When given an element that 066 * doesn't satisfy the predicate, the collection's {@code add()} and {@code 067 * addAll()} methods throw an {@link IllegalArgumentException}. When methods 068 * such as {@code removeAll()} and {@code clear()} are called on the filtered 069 * collection, only elements that satisfy the filter will be removed from the 070 * underlying collection. 071 * 072 * <p>The returned collection isn't threadsafe or serializable, even if 073 * {@code unfiltered} is. 074 * 075 * <p>Many of the filtered collection's methods, such as {@code size()}, 076 * iterate across every element in the underlying collection and determine 077 * which elements satisfy the filter. When a live view is <i>not</i> needed, 078 * it may be faster to copy {@code Iterables.filter(unfiltered, predicate)} 079 * and use the copy. 080 * 081 * <p><b>Warning:</b> {@code predicate} must be <i>consistent with equals</i>, 082 * as documented at {@link Predicate#apply}. Do not provide a predicate such 083 * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent 084 * with equals. (See {@link Iterables#filter(Iterable, Class)} for related 085 * functionality.) 086 */ 087 // TODO(kevinb): how can we omit that Iterables link when building gwt 088 // javadoc? 089 public static <E> Collection<E> filter( 090 Collection<E> unfiltered, Predicate<? super E> predicate) { 091 if (unfiltered instanceof FilteredCollection) { 092 // Support clear(), removeAll(), and retainAll() when filtering a filtered 093 // collection. 094 return ((FilteredCollection<E>) unfiltered).createCombined(predicate); 095 } 096 097 return new FilteredCollection<E>( 098 checkNotNull(unfiltered), checkNotNull(predicate)); 099 } 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 */ 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 */ 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, 139 Predicate<? super E> predicate) { 140 this.unfiltered = unfiltered; 141 this.predicate = predicate; 142 } 143 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 151 public boolean add(E element) { 152 checkArgument(predicate.apply(element)); 153 return unfiltered.add(element); 154 } 155 156 @Override 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 165 public void clear() { 166 Iterables.removeIf(unfiltered, predicate); 167 } 168 169 @Override 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 180 public boolean containsAll(Collection<?> collection) { 181 return containsAllImpl(this, collection); 182 } 183 184 @Override 185 public boolean isEmpty() { 186 return !Iterables.any(unfiltered, predicate); 187 } 188 189 @Override 190 public Iterator<E> iterator() { 191 return Iterators.filter(unfiltered.iterator(), predicate); 192 } 193 194 @Override 195 public boolean remove(Object element) { 196 return contains(element) && unfiltered.remove(element); 197 } 198 199 @Override 200 public boolean removeAll(final Collection<?> collection) { 201 return Iterables.removeIf(unfiltered, and(predicate, in(collection))); 202 } 203 204 @Override 205 public boolean retainAll(final Collection<?> collection) { 206 return Iterables.removeIf(unfiltered, and(predicate, not(in(collection)))); 207 } 208 209 @Override 210 public int size() { 211 return Iterators.size(iterator()); 212 } 213 214 @Override 215 public Object[] toArray() { 216 // creating an ArrayList so filtering happens once 217 return Lists.newArrayList(iterator()).toArray(); 218 } 219 220 @Override 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 */ 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 254 TransformedCollection(Collection<F> fromCollection, 255 Function<? super F, ? extends T> function) { 256 this.fromCollection = checkNotNull(fromCollection); 257 this.function = checkNotNull(function); 258 } 259 260 @Override public void clear() { 261 fromCollection.clear(); 262 } 263 264 @Override public boolean isEmpty() { 265 return fromCollection.isEmpty(); 266 } 267 268 @Override public Iterator<T> iterator() { 269 return Iterators.transform(fromCollection.iterator(), function); 270 } 271 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 */ 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 */ 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 */ 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 */ 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>> 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 */ 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 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 */ 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 457 @Override public int size() { 458 return size; 459 } 460 461 @Override public boolean isEmpty() { 462 return false; 463 } 464 465 @Override public Iterator<List<E>> iterator() { 466 return new OrderedPermutationIterator<E>(inputList, comparator); 467 } 468 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 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 488 OrderedPermutationIterator(List<E> list, 489 Comparator<? super E> comparator) { 490 this.nextPermutation = Lists.newArrayList(list); 491 this.comparator = comparator; 492 } 493 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 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 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 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 */ 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 566 PermutationCollection(ImmutableList<E> input) { 567 this.inputList = input; 568 } 569 570 @Override public int size() { 571 return IntMath.factorial(inputList.size()); 572 } 573 574 @Override public boolean isEmpty() { 575 return false; 576 } 577 578 @Override public Iterator<List<E>> iterator() { 579 return new PermutationIterator<E>(inputList); 580 } 581 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 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 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 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 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 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 */ 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 671 private static boolean isPositiveInt(long n) { 672 return n >= 0 && n <= Integer.MAX_VALUE; 673 } 674}