• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
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?
filter( Collection<E> unfiltered, Predicate<? super E> predicate)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    */
safeContains( Collection<?> collection, @Nullable Object object)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    */
safeRemove(Collection<?> collection, @Nullable Object object)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 
FilteredCollection(Collection<E> unfiltered, Predicate<? super E> predicate)138     FilteredCollection(Collection<E> unfiltered,
139         Predicate<? super E> predicate) {
140       this.unfiltered = unfiltered;
141       this.predicate = predicate;
142     }
143 
createCombined(Predicate<? super E> newPredicate)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
add(E element)151     public boolean add(E element) {
152       checkArgument(predicate.apply(element));
153       return unfiltered.add(element);
154     }
155 
156     @Override
addAll(Collection<? extends E> collection)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
clear()165     public void clear() {
166       Iterables.removeIf(unfiltered, predicate);
167     }
168 
169     @Override
contains(@ullable Object element)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
containsAll(Collection<?> collection)180     public boolean containsAll(Collection<?> collection) {
181       return containsAllImpl(this, collection);
182     }
183 
184     @Override
isEmpty()185     public boolean isEmpty() {
186       return !Iterables.any(unfiltered, predicate);
187     }
188 
189     @Override
iterator()190     public Iterator<E> iterator() {
191       return Iterators.filter(unfiltered.iterator(), predicate);
192     }
193 
194     @Override
remove(Object element)195     public boolean remove(Object element) {
196       return contains(element) && unfiltered.remove(element);
197     }
198 
199     @Override
removeAll(final Collection<?> collection)200     public boolean removeAll(final Collection<?> collection) {
201       return Iterables.removeIf(unfiltered, and(predicate, Predicates.<Object>in(collection)));
202     }
203 
204     @Override
retainAll(final Collection<?> collection)205     public boolean retainAll(final Collection<?> collection) {
206       return Iterables.removeIf(unfiltered, and(predicate, not(Predicates.<Object>in(collection))));
207     }
208 
209     @Override
size()210     public int size() {
211       return Iterators.size(iterator());
212     }
213 
214     @Override
toArray()215     public Object[] toArray() {
216       // creating an ArrayList so filtering happens once
217       return Lists.newArrayList(iterator()).toArray();
218     }
219 
220     @Override
toArray(T[] array)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    */
transform(Collection<F> fromCollection, Function<? super F, T> function)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 
TransformedCollection(Collection<F> fromCollection, Function<? super F, ? extends T> function)254     TransformedCollection(Collection<F> fromCollection,
255         Function<? super F, ? extends T> function) {
256       this.fromCollection = checkNotNull(fromCollection);
257       this.function = checkNotNull(function);
258     }
259 
clear()260     @Override public void clear() {
261       fromCollection.clear();
262     }
263 
isEmpty()264     @Override public boolean isEmpty() {
265       return fromCollection.isEmpty();
266     }
267 
iterator()268     @Override public Iterator<T> iterator() {
269       return Iterators.transform(fromCollection.iterator(), function);
270     }
271 
size()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    */
containsAllImpl(Collection<?> self, Collection<?> c)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    */
toStringImpl(final Collection<?> collection)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    */
newStringBuilderForCollection(int size)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    */
cast(Iterable<T> iterable)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>>
orderedPermutations(Iterable<E> elements)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    */
orderedPermutations( Iterable<E> elements, Comparator<? super E> comparator)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 
OrderedPermutationCollection(Iterable<E> input, Comparator<? super E> comparator)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      */
calculateSize( List<E> sortedInputList, Comparator<? super E> comparator)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 
size()457     @Override public int size() {
458       return size;
459     }
460 
isEmpty()461     @Override public boolean isEmpty() {
462       return false;
463     }
464 
iterator()465     @Override public Iterator<List<E>> iterator() {
466       return new OrderedPermutationIterator<E>(inputList, comparator);
467     }
468 
contains(@ullable Object obj)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 
toString()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 
OrderedPermutationIterator(List<E> list, Comparator<? super E> comparator)488     OrderedPermutationIterator(List<E> list,
489         Comparator<? super E> comparator) {
490       this.nextPermutation = Lists.newArrayList(list);
491       this.comparator = comparator;
492     }
493 
computeNext()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 
calculateNextPermutation()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 
findNextJ()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 
findNextL(int j)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    */
permutations( Collection<E> elements)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 
PermutationCollection(ImmutableList<E> input)566     PermutationCollection(ImmutableList<E> input) {
567       this.inputList = input;
568     }
569 
size()570     @Override public int size() {
571       return IntMath.factorial(inputList.size());
572     }
573 
isEmpty()574     @Override public boolean isEmpty() {
575       return false;
576     }
577 
iterator()578     @Override public Iterator<List<E>> iterator() {
579       return new PermutationIterator<E>(inputList);
580     }
581 
contains(@ullable Object obj)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 
toString()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 
PermutationIterator(List<E> list)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 
computeNext()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 
calculateNextPermutation()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 
switchDirection()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    */
isPermutation(List<?> first, List<?> second)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 
isPositiveInt(long n)671   private static boolean isPositiveInt(long n) {
672     return n >= 0 && n <= Integer.MAX_VALUE;
673   }
674 }
675