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.checkNotNull;
020    
021    import com.google.common.annotations.Beta;
022    import com.google.common.annotations.GwtCompatible;
023    import com.google.common.annotations.GwtIncompatible;
024    import com.google.common.base.Function;
025    import com.google.common.base.Optional;
026    import com.google.common.base.Predicate;
027    
028    import java.util.Comparator;
029    import java.util.Iterator;
030    import java.util.List;
031    import java.util.SortedSet;
032    
033    import javax.annotation.Nullable;
034    
035    /**
036     * {@code FluentIterable} provides a rich interface for manipulating {@code Iterable}s in a chained
037     * fashion. A {@code FluentIterable} can be created from an {@code Iterable}, or from a set of
038     * elements. The following types of methods are provided on {@code FluentIterable}:
039     * <ul>
040     * <li>chained methods which return a new {@code FluentIterable} based in some way on the contents
041     * of the current one (for example {@link #transform})
042     * <li>conversion methods which copy the {@code FluentIterable}'s contents into a new collection or
043     * array (for example {@link #toImmutableList})
044     * <li>element extraction methods which facilitate the retrieval of certain elements (for example
045     * {@link #last})
046     * <li>query methods which answer questions about the {@code FluentIterable}'s contents (for example
047     * {@link #anyMatch})
048     * </ul>
049     *
050     * <p>Here is an example that merges the lists returned by two separate database calls, transforms
051     * it by invoking {@code toString()} on each element, and returns the first 10 elements as an
052     * {@code ImmutableList}: <pre>   {@code
053     *
054     *   FluentIterable
055     *       .from(database.getClientList())
056     *       .filter(activeInLastMonth())
057     *       .transform(Functions.toStringFunction())
058     *       .limit(10)
059     *       .toImmutableList();}</pre>
060     *
061     * Anything which can be done using {@code FluentIterable} could be done in a different fashion
062     * (often with {@link Iterables}), however the use of {@code FluentIterable} makes many sets of
063     * operations significantly more concise.
064     *
065     * @author Marcin Mikosik
066     * @since 12.0
067     */
068    @Beta
069    @GwtCompatible(emulated = true)
070    public abstract class FluentIterable<E> implements Iterable<E> {
071      // We store 'iterable' and use it instead of 'this' to allow Iterables to perform instanceof
072      // checks on the _original_ iterable when FluentIterable.from is used.
073      private final Iterable<E> iterable;
074    
075      /** Constructor for use by subclasses. */
076      protected FluentIterable() {
077        this.iterable = this;
078      }
079    
080      FluentIterable(Iterable<E> iterable) {
081        this.iterable = checkNotNull(iterable);
082      }
083    
084      /**
085       * Returns a fluent iterable that wraps {@code iterable}, or {@code iterable} itself if it
086       * is already a {@code FluentIterable}.
087       */
088      public static <E> FluentIterable<E> from(final Iterable<E> iterable) {
089        return (iterable instanceof FluentIterable) ? (FluentIterable<E>) iterable
090            : new FluentIterable<E>(iterable) {
091              @Override
092              public Iterator<E> iterator() {
093                return iterable.iterator();
094              }
095            };
096      }
097    
098      /**
099       * Construct a fluent iterable from another fluent iterable. This is obviously never necessary,
100       * but is intended to help call out cases where one migration from {@code Iterable} to
101       * {@code FluentIterable} has obviated the need to explicitly convert to a {@code FluentIterable}.
102       *
103       * @deprecated instances of {@code FluentIterable} don't need to be converted to
104       *     {@code FluentIterable}
105       */
106      @Deprecated
107      public static <E> FluentIterable<E> from(FluentIterable<E> iterable) {
108        return checkNotNull(iterable);
109      }
110    
111      /**
112       * Returns a string representation of this fluent iterable, with the format
113       * {@code [e1, e2, ..., en]}.
114       */
115      @Override
116      public String toString() {
117        return Iterables.toString(iterable);
118      }
119    
120      /**
121       * Returns the number of elements in this fluent iterable.
122       */
123      public final int size() {
124        return Iterables.size(iterable);
125      }
126    
127      /**
128       * Returns {@code true} if this fluent iterable contains any object for which
129       * {@code equals(element)} is true.
130       */
131      public final boolean contains(@Nullable Object element) {
132        return Iterables.contains(iterable, element);
133      }
134    
135      /**
136       * Returns a fluent iterable whose {@code Iterator} cycles indefinitely over the elements of
137       * this fluent iterable.
138       *
139       * <p>That iterator supports {@code remove()} if {@code iterable.iterator()} does. After
140       * {@code remove()} is called, subsequent cycles omit the removed element, which is no longer in
141       * this fluent iterable. The iterator's {@code hasNext()} method returns {@code true} until
142       * this fluent iterable is empty.
143       *
144       * <p><b>Warning:</b> Typical uses of the resulting iterator may produce an infinite loop. You
145       * should use an explicit {@code break} or be certain that you will eventually remove all the
146       * elements.
147       */
148      public final FluentIterable<E> cycle() {
149        return from(Iterables.cycle(iterable));
150      }
151    
152      /**
153       * Returns the elements from this fluent iterable that satisfy a predicate. The
154       * resulting fluent iterable's iterator does not support {@code remove()}.
155       */
156      public final FluentIterable<E> filter(Predicate<? super E> predicate) {
157        return from(Iterables.filter(iterable, predicate));
158      }
159    
160      /**
161       * Returns the elements from this fluent iterable that are instances of class {@code type}.
162       *
163       * @param type the type of elements desired
164       */
165      @GwtIncompatible("Class.isInstance")
166      public final <T> FluentIterable<T> filter(Class<T> type) {
167        return from(Iterables.filter(iterable, type));
168      }
169    
170      /**
171       * Returns {@code true} if any element in this fluent iterable satisfies the predicate.
172       */
173      public final boolean anyMatch(Predicate<? super E> predicate) {
174        return Iterables.any(iterable, predicate);
175      }
176    
177      /**
178       * Returns {@code true} if every element in this fluent iterable satisfies the predicate.
179       * If this fluent iterable is empty, {@code true} is returned.
180       */
181      public final boolean allMatch(Predicate<? super E> predicate) {
182        return Iterables.all(iterable, predicate);
183      }
184    
185      /**
186       * Returns an {@link Optional} containing the first element in this fluent iterable that
187       * satisfies the given predicate, if such an element exists.
188       *
189       * <p><b>Warning:</b> avoid using a {@code predicate} that matches {@code null}. If {@code null}
190       * is matched in this fluent iterable, a {@link NullPointerException} will be thrown.
191       */
192      public final Optional<E> firstMatch(Predicate<? super E> predicate) {
193        return Iterables.tryFind(iterable, predicate);
194      }
195    
196      /**
197       * Returns a fluent iterable that applies {@code function} to each element of this
198       * fluent iterable.
199       *
200       * <p>The returned fluent iterable's iterator supports {@code remove()} if this iterable's
201       * iterator does. After a successful {@code remove()} call, this fluent iterable no longer
202       * contains the corresponding element.
203       */
204      public final <T> FluentIterable<T> transform(Function<? super E, T> function) {
205        return from(Iterables.transform(iterable, function));
206      }
207    
208      /**
209       * Applies {@code function} to each element of this fluent iterable and returns
210       * a fluent iterable with the concatenated combination of results.  {@code function}
211       * returns an Iterable of results.
212       *
213       * <p>The returned fluent iterable's iterator supports {@code remove()} if this
214       * function-returned iterables' iterator does. After a successful {@code remove()} call,
215       * the returned fluent iterable no longer contains the corresponding element.
216       *
217       * @since 13.0
218       */
219      public <T> FluentIterable<T> transformAndConcat(
220          Function<? super E, ? extends Iterable<T>> function) {
221        return from(Iterables.concat(transform(function)));
222      }
223    
224      /**
225       * Returns an {@link Optional} containing the first element in this fluent iterable.
226       * If the iterable is empty, {@code Optional.absent()} is returned.
227       *
228       * @throws NullPointerException if the first element is null; if this is a possibility, use
229       *     {@code iterator().next()} or {@link Iterables#getFirst} instead.
230       */
231      public final Optional<E> first() {
232        Iterator<E> iterator = iterable.iterator();
233        return iterator.hasNext()
234            ? Optional.of(iterator.next())
235            : Optional.<E>absent();
236      }
237    
238      /**
239       * Returns an {@link Optional} containing the last element in this fluent iterable.
240       * If the iterable is empty, {@code Optional.absent()} is returned.
241       *
242       * @throws NullPointerException if the last element is null; if this is a possibility, use
243       *     {@link Iterables#getLast} instead.
244       */
245      public final Optional<E> last() {
246        // Iterables#getLast was inlined here so we don't have to throw/catch a NSEE
247    
248        // TODO(kevinb): Support a concurrently modified collection?
249        if (iterable instanceof List) {
250          List<E> list = (List<E>) iterable;
251          if (list.isEmpty()) {
252            return Optional.absent();
253          }
254          return Optional.of(list.get(list.size() - 1));
255        }
256        Iterator<E> iterator = iterable.iterator();
257        if (!iterator.hasNext()) {
258          return Optional.absent();
259        }
260    
261        /*
262         * TODO(kevinb): consider whether this "optimization" is worthwhile. Users
263         * with SortedSets tend to know they are SortedSets and probably would not
264         * call this method.
265         */
266        if (iterable instanceof SortedSet) {
267          SortedSet<E> sortedSet = (SortedSet<E>) iterable;
268          return Optional.of(sortedSet.last());
269        }
270    
271        while (true) {
272          E current = iterator.next();
273          if (!iterator.hasNext()) {
274            return Optional.of(current);
275          }
276        }
277      }
278    
279      /**
280       * Returns a view of this fluent iterable that skips its first {@code numberToSkip}
281       * elements. If this fluent iterable contains fewer than {@code numberToSkip} elements,
282       * the returned fluent iterable skips all of its elements.
283       *
284       * <p>Modifications to this fluent iterable before a call to {@code iterator()} are
285       * reflected in the returned fluent iterable. That is, the its iterator skips the first
286       * {@code numberToSkip} elements that exist when the iterator is created, not when {@code skip()}
287       * is called.
288       *
289       * <p>The returned fluent iterable's iterator supports {@code remove()} if the
290       * {@code Iterator} of this fluent iterable supports it. Note that it is <i>not</i>
291       * possible to delete the last skipped element by immediately calling {@code remove()} on the
292       * returned fluent iterable's iterator, as the {@code Iterator} contract states that a call
293       * to {@code * remove()} before a call to {@code next()} will throw an
294       * {@link IllegalStateException}.
295       */
296      public final FluentIterable<E> skip(int numberToSkip) {
297        return from(Iterables.skip(iterable, numberToSkip));
298      }
299    
300      /**
301       * Creates a fluent iterable with the first {@code size} elements of this
302       * fluent iterable. If this fluent iterable does not contain that many elements,
303       * the returned fluent iterable will have the same behavior as this fluent iterable.
304       * The returned fluent iterable's iterator supports {@code remove()} if this
305       * fluent iterable's iterator does.
306       *
307       * @param size the maximum number of elements in the returned fluent iterable
308       * @throws IllegalArgumentException if {@code size} is negative
309       */
310      public final FluentIterable<E> limit(int size) {
311        return from(Iterables.limit(iterable, size));
312      }
313    
314      /**
315       * Determines whether this fluent iterable is empty.
316       */
317      public final boolean isEmpty() {
318        return !iterable.iterator().hasNext();
319      }
320    
321      /**
322       * Returns an {@code ImmutableList} containing all of the elements from this
323       * fluent iterable in proper sequence.
324       */
325      public final ImmutableList<E> toImmutableList() {
326        return ImmutableList.copyOf(iterable);
327      }
328    
329      /**
330       * Returns an {@code ImmutableList} containing all of the elements from this
331       * {@code FluentIterable} in the order specified by {@code comparator}.  To produce an
332       * {@code ImmutableList} sorted by its natural ordering, use
333       * {@code toSortedImmutableList(Ordering.natural())}.
334       *
335       * @param comparator the function by which to sort list elements
336       * @throws NullPointerException if any element is null
337       * @since 13.0
338       */
339      public final ImmutableList<E> toSortedImmutableList(Comparator<? super E> comparator) {
340        return Ordering.from(comparator).immutableSortedCopy(iterable);
341      }
342    
343      /**
344       * Returns an {@code ImmutableSet} containing all of the elements from this
345       * fluent iterable with duplicates removed.
346       */
347      public final ImmutableSet<E> toImmutableSet() {
348        return ImmutableSet.copyOf(iterable);
349      }
350    
351      /**
352       * Returns an {@code ImmutableSortedSet} containing all of the elements from this
353       * {@code FluentIterable} in the order specified by {@code comparator}, with duplicates
354       * (determined by {@code comaprator.compare(x, y) == 0}) removed. To produce an
355       * {@code ImmutableSortedSet} sorted by its natural ordering, use
356       * {@code toImmutableSortedSet(Ordering.natural())}.
357       *
358       * @param comparator the function by which to sort set elements
359       * @throws NullPointerException if any element is null
360       */
361      public final ImmutableSortedSet<E> toImmutableSortedSet(Comparator<? super E> comparator) {
362        return ImmutableSortedSet.copyOf(comparator, iterable);
363      }
364    
365      /**
366       * Returns an array containing all of the elements from this fluent iterable in iteration order.
367       *
368       * @param type the type of the elements
369       * @return a newly-allocated array into which all the elements of this fluent iterable have
370       *     been copied
371       */
372      @GwtIncompatible("Array.newArray(Class, int)")
373      public final E[] toArray(Class<E> type) {
374        return Iterables.toArray(iterable, type);
375      }
376    
377      /**
378       * Returns the element at the specified position in this fluent iterable.
379       *
380       * @param position position of the element to return
381       * @return the element at the specified position in this fluent iterable
382       * @throws IndexOutOfBoundsException if {@code position} is negative or greater than or equal to
383       *     the size of this fluent iterable
384       */
385      public final E get(int position) {
386        return Iterables.get(iterable, position);
387      }
388    
389      /**
390       * Function that transforms {@code Iterable<E>} into a fluent iterable.
391       */
392      private static class FromIterableFunction<E>
393          implements Function<Iterable<E>, FluentIterable<E>> {
394        @Override
395        public FluentIterable<E> apply(Iterable<E> fromObject) {
396          return FluentIterable.from(fromObject);
397        }
398      }
399    }