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