Home | History | Annotate | Download | only in collect
      1 /*
      2  * Copyright (C) 2008 The Guava Authors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.common.collect;
     18 
     19 import static com.google.common.base.Preconditions.checkArgument;
     20 import static com.google.common.base.Preconditions.checkNotNull;
     21 import static com.google.common.base.Predicates.and;
     22 import static com.google.common.base.Predicates.in;
     23 import static com.google.common.base.Predicates.not;
     24 import static com.google.common.collect.CollectPreconditions.checkNonnegative;
     25 import static com.google.common.math.LongMath.binomial;
     26 
     27 import com.google.common.annotations.Beta;
     28 import com.google.common.annotations.GwtCompatible;
     29 import com.google.common.base.Function;
     30 import com.google.common.base.Joiner;
     31 import com.google.common.base.Predicate;
     32 import com.google.common.base.Predicates;
     33 import com.google.common.math.IntMath;
     34 import com.google.common.primitives.Ints;
     35 
     36 import java.util.AbstractCollection;
     37 import java.util.ArrayList;
     38 import java.util.Arrays;
     39 import java.util.Collection;
     40 import java.util.Collections;
     41 import java.util.Comparator;
     42 import java.util.Iterator;
     43 import java.util.List;
     44 
     45 import javax.annotation.Nullable;
     46 
     47 /**
     48  * Provides static methods for working with {@code Collection} instances.
     49  *
     50  * @author Chris Povirk
     51  * @author Mike Bostock
     52  * @author Jared Levy
     53  * @since 2.0 (imported from Google Collections Library)
     54  */
     55 @GwtCompatible
     56 public final class Collections2 {
     57   private Collections2() {}
     58 
     59   /**
     60    * Returns the elements of {@code unfiltered} that satisfy a predicate. The
     61    * returned collection is a live view of {@code unfiltered}; changes to one
     62    * affect the other.
     63    *
     64    * <p>The resulting collection's iterator does not support {@code remove()},
     65    * but all other collection methods are supported. When given an element that
     66    * doesn't satisfy the predicate, the collection's {@code add()} and {@code
     67    * addAll()} methods throw an {@link IllegalArgumentException}. When methods
     68    * such as {@code removeAll()} and {@code clear()} are called on the filtered
     69    * collection, only elements that satisfy the filter will be removed from the
     70    * underlying collection.
     71    *
     72    * <p>The returned collection isn't threadsafe or serializable, even if
     73    * {@code unfiltered} is.
     74    *
     75    * <p>Many of the filtered collection's methods, such as {@code size()},
     76    * iterate across every element in the underlying collection and determine
     77    * which elements satisfy the filter. When a live view is <i>not</i> needed,
     78    * it may be faster to copy {@code Iterables.filter(unfiltered, predicate)}
     79    * and use the copy.
     80    *
     81    * <p><b>Warning:</b> {@code predicate} must be <i>consistent with equals</i>,
     82    * as documented at {@link Predicate#apply}. Do not provide a predicate such
     83    * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent
     84    * with equals. (See {@link Iterables#filter(Iterable, Class)} for related
     85    * functionality.)
     86    */
     87   // TODO(kevinb): how can we omit that Iterables link when building gwt
     88   // javadoc?
     89   public static <E> Collection<E> filter(
     90       Collection<E> unfiltered, Predicate<? super E> predicate) {
     91     if (unfiltered instanceof FilteredCollection) {
     92       // Support clear(), removeAll(), and retainAll() when filtering a filtered
     93       // collection.
     94       return ((FilteredCollection<E>) unfiltered).createCombined(predicate);
     95     }
     96 
     97     return new FilteredCollection<E>(
     98         checkNotNull(unfiltered), checkNotNull(predicate));
     99   }
    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, Predicates.<Object>in(collection)));
    202     }
    203 
    204     @Override
    205     public boolean retainAll(final Collection<?> collection) {
    206       return Iterables.removeIf(unfiltered, and(predicate, not(Predicates.<Object>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 }
    675