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.checkNotNull;
     20 
     21 import com.google.common.annotations.Beta;
     22 import com.google.common.annotations.GwtCompatible;
     23 import com.google.common.annotations.GwtIncompatible;
     24 import com.google.common.base.Function;
     25 import com.google.common.base.Optional;
     26 import com.google.common.base.Predicate;
     27 
     28 import java.util.Collection;
     29 import java.util.Comparator;
     30 import java.util.Iterator;
     31 import java.util.List;
     32 import java.util.SortedSet;
     33 
     34 import javax.annotation.CheckReturnValue;
     35 import javax.annotation.Nullable;
     36 
     37 /**
     38  * {@code FluentIterable} provides a rich interface for manipulating {@code Iterable} instances in a
     39  * chained fashion. A {@code FluentIterable} can be created from an {@code Iterable}, or from a set
     40  * of elements. The following types of methods are provided on {@code FluentIterable}:
     41  * <ul>
     42  * <li>chained methods which return a new {@code FluentIterable} based in some way on the contents
     43  * of the current one (for example {@link #transform})
     44  * <li>conversion methods which copy the {@code FluentIterable}'s contents into a new collection or
     45  * array (for example {@link #toList})
     46  * <li>element extraction methods which facilitate the retrieval of certain elements (for example
     47  * {@link #last})
     48  * <li>query methods which answer questions about the {@code FluentIterable}'s contents (for example
     49  * {@link #anyMatch})
     50  * </ul>
     51  *
     52  * <p>Here is an example that merges the lists returned by two separate database calls, transforms
     53  * it by invoking {@code toString()} on each element, and returns the first 10 elements as an
     54  * {@code ImmutableList}: <pre>   {@code
     55  *
     56  *   FluentIterable
     57  *       .from(database.getClientList())
     58  *       .filter(activeInLastMonth())
     59  *       .transform(Functions.toStringFunction())
     60  *       .limit(10)
     61  *       .toList();}</pre>
     62  *
     63  * <p>Anything which can be done using {@code FluentIterable} could be done in a different fashion
     64  * (often with {@link Iterables}), however the use of {@code FluentIterable} makes many sets of
     65  * operations significantly more concise.
     66  *
     67  * @author Marcin Mikosik
     68  * @since 12.0
     69  */
     70 @GwtCompatible(emulated = true)
     71 public abstract class FluentIterable<E> implements Iterable<E> {
     72   // We store 'iterable' and use it instead of 'this' to allow Iterables to perform instanceof
     73   // checks on the _original_ iterable when FluentIterable.from is used.
     74   private final Iterable<E> iterable;
     75 
     76   /** Constructor for use by subclasses. */
     77   protected FluentIterable() {
     78     this.iterable = this;
     79   }
     80 
     81   FluentIterable(Iterable<E> iterable) {
     82     this.iterable = checkNotNull(iterable);
     83   }
     84 
     85   /**
     86    * Returns a fluent iterable that wraps {@code iterable}, or {@code iterable} itself if it
     87    * is already a {@code FluentIterable}.
     88    */
     89   public static <E> FluentIterable<E> from(final Iterable<E> iterable) {
     90     return (iterable instanceof FluentIterable) ? (FluentIterable<E>) iterable
     91         : new FluentIterable<E>(iterable) {
     92           @Override
     93           public Iterator<E> iterator() {
     94             return iterable.iterator();
     95           }
     96         };
     97   }
     98 
     99   /**
    100    * Construct a fluent iterable from another fluent iterable. This is obviously never necessary,
    101    * but is intended to help call out cases where one migration from {@code Iterable} to
    102    * {@code FluentIterable} has obviated the need to explicitly convert to a {@code FluentIterable}.
    103    *
    104    * @deprecated instances of {@code FluentIterable} don't need to be converted to
    105    *     {@code FluentIterable}
    106    */
    107   @Deprecated
    108   public static <E> FluentIterable<E> from(FluentIterable<E> iterable) {
    109     return checkNotNull(iterable);
    110   }
    111 
    112   /**
    113    * Returns a string representation of this fluent iterable, with the format
    114    * {@code [e1, e2, ..., en]}.
    115    */
    116   @Override
    117   public String toString() {
    118     return Iterables.toString(iterable);
    119   }
    120 
    121   /**
    122    * Returns the number of elements in this fluent iterable.
    123    */
    124   public final int size() {
    125     return Iterables.size(iterable);
    126   }
    127 
    128   /**
    129    * Returns {@code true} if this fluent iterable contains any object for which
    130    * {@code equals(element)} is true.
    131    */
    132   public final boolean contains(@Nullable Object element) {
    133     return Iterables.contains(iterable, element);
    134   }
    135 
    136   /**
    137    * Returns a fluent iterable whose {@code Iterator} cycles indefinitely over the elements of
    138    * this fluent iterable.
    139    *
    140    * <p>That iterator supports {@code remove()} if {@code iterable.iterator()} does. After
    141    * {@code remove()} is called, subsequent cycles omit the removed element, which is no longer in
    142    * this fluent iterable. The iterator's {@code hasNext()} method returns {@code true} until
    143    * this fluent iterable is empty.
    144    *
    145    * <p><b>Warning:</b> Typical uses of the resulting iterator may produce an infinite loop. You
    146    * should use an explicit {@code break} or be certain that you will eventually remove all the
    147    * elements.
    148    */
    149   @CheckReturnValue
    150   public final FluentIterable<E> cycle() {
    151     return from(Iterables.cycle(iterable));
    152   }
    153 
    154   /**
    155    * Returns the elements from this fluent iterable that satisfy a predicate. The
    156    * resulting fluent iterable's iterator does not support {@code remove()}.
    157    */
    158   @CheckReturnValue
    159   public final FluentIterable<E> filter(Predicate<? super E> predicate) {
    160     return from(Iterables.filter(iterable, predicate));
    161   }
    162 
    163   /**
    164    * Returns the elements from this fluent iterable that are instances of class {@code type}.
    165    *
    166    * @param type the type of elements desired
    167    */
    168   @GwtIncompatible("Class.isInstance")
    169   @CheckReturnValue
    170   public final <T> FluentIterable<T> filter(Class<T> type) {
    171     return from(Iterables.filter(iterable, type));
    172   }
    173 
    174   /**
    175    * Returns {@code true} if any element in this fluent iterable satisfies the predicate.
    176    */
    177   public final boolean anyMatch(Predicate<? super E> predicate) {
    178     return Iterables.any(iterable, predicate);
    179   }
    180 
    181   /**
    182    * Returns {@code true} if every element in this fluent iterable satisfies the predicate.
    183    * If this fluent iterable is empty, {@code true} is returned.
    184    */
    185   public final boolean allMatch(Predicate<? super E> predicate) {
    186     return Iterables.all(iterable, predicate);
    187   }
    188 
    189   /**
    190    * Returns an {@link Optional} containing the first element in this fluent iterable that
    191    * satisfies the given predicate, if such an element exists.
    192    *
    193    * <p><b>Warning:</b> avoid using a {@code predicate} that matches {@code null}. If {@code null}
    194    * is matched in this fluent iterable, a {@link NullPointerException} will be thrown.
    195    */
    196   public final Optional<E> firstMatch(Predicate<? super E> predicate) {
    197     return Iterables.tryFind(iterable, predicate);
    198   }
    199 
    200   /**
    201    * Returns a fluent iterable that applies {@code function} to each element of this
    202    * fluent iterable.
    203    *
    204    * <p>The returned fluent iterable's iterator supports {@code remove()} if this iterable's
    205    * iterator does. After a successful {@code remove()} call, this fluent iterable no longer
    206    * contains the corresponding element.
    207    */
    208   public final <T> FluentIterable<T> transform(Function<? super E, T> function) {
    209     return from(Iterables.transform(iterable, function));
    210   }
    211 
    212   /**
    213    * Applies {@code function} to each element of this fluent iterable and returns
    214    * a fluent iterable with the concatenated combination of results.  {@code function}
    215    * returns an Iterable of results.
    216    *
    217    * <p>The returned fluent iterable's iterator supports {@code remove()} if this
    218    * function-returned iterables' iterator does. After a successful {@code remove()} call,
    219    * the returned fluent iterable no longer contains the corresponding element.
    220    *
    221    * @since 13.0 (required {@code Function<E, Iterable<T>>} until 14.0)
    222    */
    223   public <T> FluentIterable<T> transformAndConcat(
    224       Function<? super E, ? extends Iterable<? extends T>> function) {
    225     return from(Iterables.concat(transform(function)));
    226   }
    227 
    228   /**
    229    * Returns an {@link Optional} containing the first element in this fluent iterable.
    230    * If the iterable is empty, {@code Optional.absent()} is returned.
    231    *
    232    * @throws NullPointerException if the first element is null; if this is a possibility, use
    233    *     {@code iterator().next()} or {@link Iterables#getFirst} instead.
    234    */
    235   public final Optional<E> first() {
    236     Iterator<E> iterator = iterable.iterator();
    237     return iterator.hasNext()
    238         ? Optional.of(iterator.next())
    239         : Optional.<E>absent();
    240   }
    241 
    242   /**
    243    * Returns an {@link Optional} containing the last element in this fluent iterable.
    244    * If the iterable is empty, {@code Optional.absent()} is returned.
    245    *
    246    * @throws NullPointerException if the last element is null; if this is a possibility, use
    247    *     {@link Iterables#getLast} instead.
    248    */
    249   public final Optional<E> last() {
    250     // Iterables#getLast was inlined here so we don't have to throw/catch a NSEE
    251 
    252     // TODO(kevinb): Support a concurrently modified collection?
    253     if (iterable instanceof List) {
    254       List<E> list = (List<E>) iterable;
    255       if (list.isEmpty()) {
    256         return Optional.absent();
    257       }
    258       return Optional.of(list.get(list.size() - 1));
    259     }
    260     Iterator<E> iterator = iterable.iterator();
    261     if (!iterator.hasNext()) {
    262       return Optional.absent();
    263     }
    264 
    265     /*
    266      * TODO(kevinb): consider whether this "optimization" is worthwhile. Users
    267      * with SortedSets tend to know they are SortedSets and probably would not
    268      * call this method.
    269      */
    270     if (iterable instanceof SortedSet) {
    271       SortedSet<E> sortedSet = (SortedSet<E>) iterable;
    272       return Optional.of(sortedSet.last());
    273     }
    274 
    275     while (true) {
    276       E current = iterator.next();
    277       if (!iterator.hasNext()) {
    278         return Optional.of(current);
    279       }
    280     }
    281   }
    282 
    283   /**
    284    * Returns a view of this fluent iterable that skips its first {@code numberToSkip}
    285    * elements. If this fluent iterable contains fewer than {@code numberToSkip} elements,
    286    * the returned fluent iterable skips all of its elements.
    287    *
    288    * <p>Modifications to this fluent iterable before a call to {@code iterator()} are
    289    * reflected in the returned fluent iterable. That is, the its iterator skips the first
    290    * {@code numberToSkip} elements that exist when the iterator is created, not when {@code skip()}
    291    * is called.
    292    *
    293    * <p>The returned fluent iterable's iterator supports {@code remove()} if the
    294    * {@code Iterator} of this fluent iterable supports it. Note that it is <i>not</i>
    295    * possible to delete the last skipped element by immediately calling {@code remove()} on the
    296    * returned fluent iterable's iterator, as the {@code Iterator} contract states that a call
    297    * to {@code * remove()} before a call to {@code next()} will throw an
    298    * {@link IllegalStateException}.
    299    */
    300   @CheckReturnValue
    301   public final FluentIterable<E> skip(int numberToSkip) {
    302     return from(Iterables.skip(iterable, numberToSkip));
    303   }
    304 
    305   /**
    306    * Creates a fluent iterable with the first {@code size} elements of this
    307    * fluent iterable. If this fluent iterable does not contain that many elements,
    308    * the returned fluent iterable will have the same behavior as this fluent iterable.
    309    * The returned fluent iterable's iterator supports {@code remove()} if this
    310    * fluent iterable's iterator does.
    311    *
    312    * @param size the maximum number of elements in the returned fluent iterable
    313    * @throws IllegalArgumentException if {@code size} is negative
    314    */
    315   @CheckReturnValue
    316   public final FluentIterable<E> limit(int size) {
    317     return from(Iterables.limit(iterable, size));
    318   }
    319 
    320   /**
    321    * Determines whether this fluent iterable is empty.
    322    */
    323   public final boolean isEmpty() {
    324     return !iterable.iterator().hasNext();
    325   }
    326 
    327   /**
    328    * Returns an {@code ImmutableList} containing all of the elements from this fluent iterable in
    329    * proper sequence.
    330    *
    331    * @since 14.0 (since 12.0 as {@code toImmutableList()}).
    332    */
    333   public final ImmutableList<E> toList() {
    334     return ImmutableList.copyOf(iterable);
    335   }
    336 
    337   /**
    338    * Returns an {@code ImmutableList} containing all of the elements from this {@code
    339    * FluentIterable} in the order specified by {@code comparator}.  To produce an {@code
    340    * ImmutableList} sorted by its natural ordering, use {@code toSortedList(Ordering.natural())}.
    341    *
    342    * @param comparator the function by which to sort list elements
    343    * @throws NullPointerException if any element is null
    344    * @since 14.0 (since 13.0 as {@code toSortedImmutableList()}).
    345    */
    346   @Beta
    347   public final ImmutableList<E> toSortedList(Comparator<? super E> comparator) {
    348     return Ordering.from(comparator).immutableSortedCopy(iterable);
    349   }
    350 
    351   /**
    352    * Returns an {@code ImmutableSet} containing all of the elements from this fluent iterable with
    353    * duplicates removed.
    354    *
    355    * @since 14.0 (since 12.0 as {@code toImmutableSet()}).
    356    */
    357   public final ImmutableSet<E> toSet() {
    358     return ImmutableSet.copyOf(iterable);
    359   }
    360 
    361   /**
    362    * Returns an {@code ImmutableSortedSet} containing all of the elements from this {@code
    363    * FluentIterable} in the order specified by {@code comparator}, with duplicates (determined by
    364    * {@code comparator.compare(x, y) == 0}) removed. To produce an {@code ImmutableSortedSet} sorted
    365    * by its natural ordering, use {@code toSortedSet(Ordering.natural())}.
    366    *
    367    * @param comparator the function by which to sort set elements
    368    * @throws NullPointerException if any element is null
    369    * @since 14.0 (since 12.0 as {@code toImmutableSortedSet()}).
    370    */
    371   public final ImmutableSortedSet<E> toSortedSet(Comparator<? super E> comparator) {
    372     return ImmutableSortedSet.copyOf(comparator, iterable);
    373   }
    374 
    375   /**
    376    * Returns an immutable map for which the elements of this {@code FluentIterable} are the keys in
    377    * the same order, mapped to values by the given function. If this iterable contains duplicate
    378    * elements, the returned map will contain each distinct element once in the order it first
    379    * appears.
    380    *
    381    * @throws NullPointerException if any element of this iterable is {@code null}, or if {@code
    382    *     valueFunction} produces {@code null} for any key
    383    * @since 14.0
    384    */
    385   public final <V> ImmutableMap<E, V> toMap(Function<? super E, V> valueFunction) {
    386     return Maps.toMap(iterable, valueFunction);
    387   }
    388 
    389   /**
    390    * Creates an index {@code ImmutableListMultimap} that contains the results of applying a
    391    * specified function to each item in this {@code FluentIterable} of values. Each element of this
    392    * iterable will be stored as a value in the resulting multimap, yielding a multimap with the same
    393    * size as this iterable. The key used to store that value in the multimap will be the result of
    394    * calling the function on that value. The resulting multimap is created as an immutable snapshot.
    395    * In the returned multimap, keys appear in the order they are first encountered, and the values
    396    * corresponding to each key appear in the same order as they are encountered.
    397    *
    398    * @param keyFunction the function used to produce the key for each value
    399    * @throws NullPointerException if any of the following cases is true:
    400    *     <ul>
    401    *       <li>{@code keyFunction} is null
    402    *       <li>An element in this fluent iterable is null
    403    *       <li>{@code keyFunction} returns {@code null} for any element of this iterable
    404    *     </ul>
    405    * @since 14.0
    406    */
    407   public final <K> ImmutableListMultimap<K, E> index(Function<? super E, K> keyFunction) {
    408     return Multimaps.index(iterable, keyFunction);
    409   }
    410 
    411   /**
    412    * Returns an immutable map for which the {@link java.util.Map#values} are the elements of this
    413    * {@code FluentIterable} in the given order, and each key is the product of invoking a supplied
    414    * function on its corresponding value.
    415    *
    416    * @param keyFunction the function used to produce the key for each value
    417    * @throws IllegalArgumentException if {@code keyFunction} produces the same key for more than one
    418    *     value in this fluent iterable
    419    * @throws NullPointerException if any element of this fluent iterable is null, or if
    420    *     {@code keyFunction} produces {@code null} for any value
    421    * @since 14.0
    422    */
    423   public final <K> ImmutableMap<K, E> uniqueIndex(Function<? super E, K> keyFunction) {
    424     return Maps.uniqueIndex(iterable, keyFunction);
    425   }
    426 
    427   /**
    428    * Returns an {@code ImmutableList} containing all of the elements from this
    429    * fluent iterable in proper sequence.
    430    *
    431    * @deprecated Use {@link #toList()} instead. This method is scheduled for removal in Guava 15.0.
    432    */
    433   @Deprecated
    434   public final ImmutableList<E> toImmutableList() {
    435     return toList();
    436   }
    437 
    438   /**
    439    * Returns an {@code ImmutableList} containing all of the elements from this
    440    * {@code FluentIterable} in the order specified by {@code comparator}.  To produce an
    441    * {@code ImmutableList} sorted by its natural ordering, use
    442    * {@code toSortedImmutableList(Ordering.natural())}.
    443    *
    444    * @param comparator the function by which to sort list elements
    445    * @throws NullPointerException if any element is null
    446    * @since 13.0
    447    * @deprecated Use {@link #toSortedList(Comparator)} instead. This method is scheduled for removal
    448    *     in Guava 15.0.
    449    */
    450   @Deprecated
    451   public final ImmutableList<E> toSortedImmutableList(
    452       Comparator<? super E> comparator) {
    453     return toSortedList(comparator);
    454   }
    455 
    456   /**
    457    * Returns an {@code ImmutableSet} containing all of the elements from this
    458    * fluent iterable with duplicates removed.
    459    *
    460    * @deprecated Use {@link #toSet()} instead. This method is scheduled for removal in Guava 15.0.
    461    */
    462   @Deprecated
    463   public final ImmutableSet<E> toImmutableSet() {
    464     return toSet();
    465   }
    466 
    467   /**
    468    * Returns an {@code ImmutableSortedSet} containing all of the elements from this
    469    * {@code FluentIterable} in the order specified by {@code comparator}, with duplicates
    470    * (determined by {@code comparator.compare(x, y) == 0}) removed. To produce an
    471    * {@code ImmutableSortedSet} sorted by its natural ordering, use
    472    * {@code toImmutableSortedSet(Ordering.natural())}.
    473    *
    474    * @param comparator the function by which to sort set elements
    475    * @throws NullPointerException if any element is null
    476    * @deprecated Use {@link #toSortedSet(Comparator)} instead. This method is scheduled for removal
    477    *     in Guava 15.0.
    478    */
    479   @Deprecated
    480   public final ImmutableSortedSet<E> toImmutableSortedSet(
    481       Comparator<? super E> comparator) {
    482     return toSortedSet(comparator);
    483   }
    484 
    485   /**
    486    * Returns an array containing all of the elements from this fluent iterable in iteration order.
    487    *
    488    * @param type the type of the elements
    489    * @return a newly-allocated array into which all the elements of this fluent iterable have
    490    *     been copied
    491    */
    492   @GwtIncompatible("Array.newArray(Class, int)")
    493   public final E[] toArray(Class<E> type) {
    494     return Iterables.toArray(iterable, type);
    495   }
    496 
    497   /**
    498    * Copies all the elements from this fluent iterable to {@code collection}. This is equivalent to
    499    * calling {@code Iterables.addAll(collection, this)}.
    500    *
    501    * @param collection the collection to copy elements to
    502    * @return {@code collection}, for convenience
    503    * @since 14.0
    504    */
    505   public final <C extends Collection<? super E>> C copyInto(C collection) {
    506     checkNotNull(collection);
    507     if (iterable instanceof Collection) {
    508       collection.addAll(Collections2.cast(iterable));
    509     } else {
    510       for (E item : iterable) {
    511         collection.add(item);
    512       }
    513     }
    514     return collection;
    515   }
    516 
    517   /**
    518    * Returns the element at the specified position in this fluent iterable.
    519    *
    520    * @param position position of the element to return
    521    * @return the element at the specified position in this fluent iterable
    522    * @throws IndexOutOfBoundsException if {@code position} is negative or greater than or equal to
    523    *     the size of this fluent iterable
    524    */
    525   public final E get(int position) {
    526     return Iterables.get(iterable, position);
    527   }
    528 
    529   /**
    530    * Function that transforms {@code Iterable<E>} into a fluent iterable.
    531    */
    532   private static class FromIterableFunction<E>
    533       implements Function<Iterable<E>, FluentIterable<E>> {
    534     @Override
    535     public FluentIterable<E> apply(Iterable<E> fromObject) {
    536       return FluentIterable.from(fromObject);
    537     }
    538   }
    539 }
    540