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
017package com.google.common.collect;
018
019import static com.google.common.base.Preconditions.checkNotNull;
020
021import com.google.common.annotations.Beta;
022import com.google.common.annotations.GwtCompatible;
023import com.google.common.annotations.GwtIncompatible;
024import com.google.common.base.Function;
025import com.google.common.base.Optional;
026import com.google.common.base.Predicate;
027
028import java.util.Comparator;
029import java.util.Iterator;
030import java.util.List;
031import java.util.SortedSet;
032
033import 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)
070public 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}