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