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