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