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