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 /** 333 * Returns a {@link Collection} of all the permutations of the specified {@link Iterable}. 334 * 335 * <p><i>Notes:</i> This is an implementation of the algorithm for Lexicographical Permutations 336 * Generation, described in Knuth's "The Art of Computer Programming", Volume 4, Chapter 7, 337 * Section 7.2.1.2. The iteration order follows the lexicographical order. This means that the 338 * first permutation will be in ascending order, and the last will be in descending order. 339 * 340 * <p>Duplicate elements are considered equal. For example, the list [1, 1] will have only one 341 * permutation, instead of two. This is why the elements have to implement {@link Comparable}. 342 * 343 * <p>An empty iterable has only one permutation, which is an empty list. 344 * 345 * <p>This method is equivalent to {@code Collections2.orderedPermutations(list, 346 * Ordering.natural())}. 347 * 348 * @param elements the original iterable whose elements have to be permuted. 349 * @return an immutable {@link Collection} containing all the different permutations of the 350 * original iterable. 351 * @throws NullPointerException if the specified iterable is null or has any null elements. 352 * @since 12.0 353 */ 354 @Beta 355 public static <E extends Comparable<? super E>> Collection<List<E>> orderedPermutations( 356 Iterable<E> elements) { 357 return orderedPermutations(elements, Ordering.natural()); 358 } 359 360 /** 361 * Returns a {@link Collection} of all the permutations of the specified {@link Iterable} using 362 * the specified {@link Comparator} for establishing the lexicographical ordering. 363 * 364 * <p>Examples: 365 * 366 * <pre>{@code 367 * for (List<String> perm : orderedPermutations(asList("b", "c", "a"))) { 368 * println(perm); 369 * } 370 * // -> ["a", "b", "c"] 371 * // -> ["a", "c", "b"] 372 * // -> ["b", "a", "c"] 373 * // -> ["b", "c", "a"] 374 * // -> ["c", "a", "b"] 375 * // -> ["c", "b", "a"] 376 * 377 * for (List<Integer> perm : orderedPermutations(asList(1, 2, 2, 1))) { 378 * println(perm); 379 * } 380 * // -> [1, 1, 2, 2] 381 * // -> [1, 2, 1, 2] 382 * // -> [1, 2, 2, 1] 383 * // -> [2, 1, 1, 2] 384 * // -> [2, 1, 2, 1] 385 * // -> [2, 2, 1, 1] 386 * }</pre> 387 * 388 * <p><i>Notes:</i> This is an implementation of the algorithm for Lexicographical Permutations 389 * Generation, described in Knuth's "The Art of Computer Programming", Volume 4, Chapter 7, 390 * Section 7.2.1.2. The iteration order follows the lexicographical order. This means that the 391 * first permutation will be in ascending order, and the last will be in descending order. 392 * 393 * <p>Elements that compare equal are considered equal and no new permutations are created by 394 * swapping them. 395 * 396 * <p>An empty iterable has only one permutation, which is an empty list. 397 * 398 * @param elements the original iterable whose elements have to be permuted. 399 * @param comparator a comparator for the iterable's elements. 400 * @return an immutable {@link Collection} containing all the different permutations of the 401 * original iterable. 402 * @throws NullPointerException If the specified iterable is null, has any null elements, or if 403 * the specified comparator is null. 404 * @since 12.0 405 */ 406 @Beta 407 public static <E> Collection<List<E>> orderedPermutations( 408 Iterable<E> elements, Comparator<? super E> comparator) { 409 return new OrderedPermutationCollection<E>(elements, comparator); 410 } 411 412 private static final class OrderedPermutationCollection<E> extends AbstractCollection<List<E>> { 413 final ImmutableList<E> inputList; 414 final Comparator<? super E> comparator; 415 final int size; 416 417 OrderedPermutationCollection(Iterable<E> input, Comparator<? super E> comparator) { 418 this.inputList = ImmutableList.sortedCopyOf(comparator, input); 419 this.comparator = comparator; 420 this.size = calculateSize(inputList, comparator); 421 } 422 423 /** 424 * The number of permutations with repeated elements is calculated as follows: 425 * 426 * <ul> 427 * <li>For an empty list, it is 1 (base case). 428 * <li>When r numbers are added to a list of n-r elements, the number of permutations is 429 * increased by a factor of (n choose r). 430 * </ul> 431 */ 432 private static <E> int calculateSize( 433 List<E> sortedInputList, Comparator<? super E> comparator) { 434 int permutations = 1; 435 int n = 1; 436 int r = 1; 437 while (n < sortedInputList.size()) { 438 int comparison = comparator.compare(sortedInputList.get(n - 1), sortedInputList.get(n)); 439 if (comparison < 0) { 440 // We move to the next non-repeated element. 441 permutations = IntMath.saturatedMultiply(permutations, IntMath.binomial(n, r)); 442 r = 0; 443 if (permutations == Integer.MAX_VALUE) { 444 return Integer.MAX_VALUE; 445 } 446 } 447 n++; 448 r++; 449 } 450 return IntMath.saturatedMultiply(permutations, IntMath.binomial(n, r)); 451 } 452 453 @Override 454 public int size() { 455 return size; 456 } 457 458 @Override 459 public boolean isEmpty() { 460 return false; 461 } 462 463 @Override 464 public Iterator<List<E>> iterator() { 465 return new OrderedPermutationIterator<E>(inputList, comparator); 466 } 467 468 @Override 469 public boolean contains(@NullableDecl 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 478 public String toString() { 479 return "orderedPermutationCollection(" + inputList + ")"; 480 } 481 } 482 483 private static final class OrderedPermutationIterator<E> extends AbstractIterator<List<E>> { 484 @NullableDecl List<E> nextPermutation; 485 final Comparator<? super E> comparator; 486 487 OrderedPermutationIterator(List<E> list, Comparator<? super E> comparator) { 488 this.nextPermutation = Lists.newArrayList(list); 489 this.comparator = comparator; 490 } 491 492 @Override 493 protected List<E> computeNext() { 494 if (nextPermutation == null) { 495 return endOfData(); 496 } 497 ImmutableList<E> next = ImmutableList.copyOf(nextPermutation); 498 calculateNextPermutation(); 499 return next; 500 } 501 502 void calculateNextPermutation() { 503 int j = findNextJ(); 504 if (j == -1) { 505 nextPermutation = null; 506 return; 507 } 508 509 int l = findNextL(j); 510 Collections.swap(nextPermutation, j, l); 511 int n = nextPermutation.size(); 512 Collections.reverse(nextPermutation.subList(j + 1, n)); 513 } 514 515 int findNextJ() { 516 for (int k = nextPermutation.size() - 2; k >= 0; k--) { 517 if (comparator.compare(nextPermutation.get(k), nextPermutation.get(k + 1)) < 0) { 518 return k; 519 } 520 } 521 return -1; 522 } 523 524 int findNextL(int j) { 525 E ak = nextPermutation.get(j); 526 for (int l = nextPermutation.size() - 1; l > j; l--) { 527 if (comparator.compare(ak, nextPermutation.get(l)) < 0) { 528 return l; 529 } 530 } 531 throw new AssertionError("this statement should be unreachable"); 532 } 533 } 534 535 /** 536 * Returns a {@link Collection} of all the permutations of the specified {@link Collection}. 537 * 538 * <p><i>Notes:</i> This is an implementation of the Plain Changes algorithm for permutations 539 * generation, described in Knuth's "The Art of Computer Programming", Volume 4, Chapter 7, 540 * Section 7.2.1.2. 541 * 542 * <p>If the input list contains equal elements, some of the generated permutations will be equal. 543 * 544 * <p>An empty collection has only one permutation, which is an empty list. 545 * 546 * @param elements the original collection whose elements have to be permuted. 547 * @return an immutable {@link Collection} containing all the different permutations of the 548 * original collection. 549 * @throws NullPointerException if the specified collection is null or has any null elements. 550 * @since 12.0 551 */ 552 @Beta 553 public static <E> Collection<List<E>> permutations(Collection<E> elements) { 554 return new PermutationCollection<E>(ImmutableList.copyOf(elements)); 555 } 556 557 private static final class PermutationCollection<E> extends AbstractCollection<List<E>> { 558 final ImmutableList<E> inputList; 559 560 PermutationCollection(ImmutableList<E> input) { 561 this.inputList = input; 562 } 563 564 @Override 565 public int size() { 566 return IntMath.factorial(inputList.size()); 567 } 568 569 @Override 570 public boolean isEmpty() { 571 return false; 572 } 573 574 @Override 575 public Iterator<List<E>> iterator() { 576 return new PermutationIterator<E>(inputList); 577 } 578 579 @Override 580 public boolean contains(@NullableDecl Object obj) { 581 if (obj instanceof List) { 582 List<?> list = (List<?>) obj; 583 return isPermutation(inputList, list); 584 } 585 return false; 586 } 587 588 @Override 589 public String toString() { 590 return "permutations(" + inputList + ")"; 591 } 592 } 593 594 private static class PermutationIterator<E> extends AbstractIterator<List<E>> { 595 final List<E> list; 596 final int[] c; 597 final int[] o; 598 int j; 599 600 PermutationIterator(List<E> list) { 601 this.list = new ArrayList<E>(list); 602 int n = list.size(); 603 c = new int[n]; 604 o = new int[n]; 605 Arrays.fill(c, 0); 606 Arrays.fill(o, 1); 607 j = Integer.MAX_VALUE; 608 } 609 610 @Override 611 protected List<E> computeNext() { 612 if (j <= 0) { 613 return endOfData(); 614 } 615 ImmutableList<E> next = ImmutableList.copyOf(list); 616 calculateNextPermutation(); 617 return next; 618 } 619 620 void calculateNextPermutation() { 621 j = list.size() - 1; 622 int s = 0; 623 624 // Handle the special case of an empty list. Skip the calculation of the 625 // next permutation. 626 if (j == -1) { 627 return; 628 } 629 630 while (true) { 631 int q = c[j] + o[j]; 632 if (q < 0) { 633 switchDirection(); 634 continue; 635 } 636 if (q == j + 1) { 637 if (j == 0) { 638 break; 639 } 640 s++; 641 switchDirection(); 642 continue; 643 } 644 645 Collections.swap(list, j - c[j] + s, j - q + s); 646 c[j] = q; 647 break; 648 } 649 } 650 651 void switchDirection() { 652 o[j] = -o[j]; 653 j--; 654 } 655 } 656 657 /** Returns {@code true} if the second list is a permutation of the first. */ 658 private static boolean isPermutation(List<?> first, List<?> second) { 659 if (first.size() != second.size()) { 660 return false; 661 } 662 ObjectCountHashMap<?> firstCounts = counts(first); 663 ObjectCountHashMap<?> secondCounts = counts(second); 664 if (first.size() != second.size()) { 665 return false; 666 } 667 for (int i = 0; i < first.size(); i++) { 668 if (firstCounts.getValue(i) != secondCounts.get(firstCounts.getKey(i))) { 669 return false; 670 } 671 } 672 return true; 673 } 674 675 private static <E> ObjectCountHashMap<E> counts(Collection<E> collection) { 676 ObjectCountHashMap<E> map = new ObjectCountHashMap<>(); 677 for (E e : collection) { 678 map.put(e, map.get(e) + 1); 679 } 680 return map; 681 } 682}