View Javadoc
1   /*
2    * Copyright (C) 2008 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5    * in compliance with the License. You may obtain a copy of the License at
6    *
7    * http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software distributed under the License
10   * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11   * or implied. See the License for the specific language governing permissions and limitations under
12   * the License.
13   */
14  
15  package com.google.common.collect;
16  
17  import static com.google.common.base.Preconditions.checkNotNull;
18  
19  import com.google.common.annotations.Beta;
20  import com.google.common.annotations.GwtCompatible;
21  import com.google.common.annotations.GwtIncompatible;
22  import com.google.common.base.Function;
23  import com.google.common.base.Joiner;
24  import com.google.common.base.Optional;
25  import com.google.common.base.Predicate;
26  import com.google.errorprone.annotations.CanIgnoreReturnValue;
27  import java.util.Arrays;
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  import java.util.stream.Stream;
34  import javax.annotation.Nullable;
35  
36  /**
37   * A discouraged (but not deprecated) precursor to Java's superior {@link Stream} library.
38   *
39   * <p>The following types of methods are provided:
40   *
41   * <ul>
42   * <li>chaining 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>element extraction methods which facilitate the retrieval of certain elements (for example
45   *     {@link #last})
46   * <li>query methods which answer questions about the {@code FluentIterable}'s contents (for example
47   *     {@link #anyMatch})
48   * <li>conversion methods which copy the {@code FluentIterable}'s contents into a new collection or
49   *     array (for example {@link #toList})
50   * </ul>
51   *
52   * <p>Several lesser-used features are currently available only as static methods on the {@link
53   * Iterables} class.
54   *
55   * <a name="streams"></a>
56   * <h3>Comparison to streams</h3>
57   *
58   * <p>{@link Stream} is similar to this class, but generally more powerful, and certainly more
59   * standard. Key differences include:
60   *
61   * <ul>
62   * <li>A stream is <i>single-use</i>; it becomes invalid as soon as any "terminal operation" such as
63   *     {@code findFirst()} or {@code iterator()} is invoked. (Even though {@code Stream} contains
64   *     all the right method <i>signatures</i> to implement {@link Iterable}, it does not actually do
65   *     so, to avoid implying repeat-iterability.) {@code FluentIterable}, on the other hand, is
66   *     multiple-use, and does implement {@link Iterable}.
67   * <li>Streams offer many features not found here, including {@code min/max}, {@code distinct},
68   *     {@code reduce}, {@code sorted}, the very powerful {@code collect}, and built-in support for
69   *     parallelizing stream operations.
70   * <li>{@code FluentIterable} contains several features not available on {@code Stream}, which are
71   *     noted in the method descriptions below.
72   * <li>Streams include primitive-specialized variants such as {@code IntStream}, the use of which is
73   *     strongly recommended.
74   * <li>Streams are standard Java, not requiring a third-party dependency.
75   * </ul>
76   *
77   * <h3>Example</h3>
78   *
79   * <p>Here is an example that accepts a list from a database call, filters it based on a predicate,
80   * transforms it by invoking {@code toString()} on each element, and returns the first 10 elements
81   * as a {@code List}:
82   *
83   * <pre>{@code
84   * ImmutableList<String> results =
85   *     FluentIterable.from(database.getClientList())
86   *         .filter(Client::isActiveInLastMonth)
87   *         .transform(Object::toString)
88   *         .limit(10)
89   *         .toList();
90   * }</pre>
91   *
92   * The approximate stream equivalent is:
93   *
94   * <pre>{@code
95   * List<String> results =
96   *     database.getClientList()
97   *         .stream()
98   *         .filter(Client::isActiveInLastMonth)
99   *         .map(Object::toString)
100  *         .limit(10)
101  *         .collect(Collectors.toList());
102  * }</pre>
103  *
104  * @author Marcin Mikosik
105  * @since 12.0
106  */
107 @GwtCompatible(emulated = true)
108 public abstract class FluentIterable<E> implements Iterable<E> {
109   // We store 'iterable' and use it instead of 'this' to allow Iterables to perform instanceof
110   // checks on the _original_ iterable when FluentIterable.from is used.
111   // To avoid a self retain cycle under j2objc, we store Optional.absent() instead of
112   // Optional.of(this). To access the iterator delegate, call #getDelegate(), which converts to
113   // absent() back to 'this'.
114   private final Optional<Iterable<E>> iterableDelegate;
115 
116   /** Constructor for use by subclasses. */
117   protected FluentIterable() {
118     this.iterableDelegate = Optional.absent();
119   }
120 
121   FluentIterable(Iterable<E> iterable) {
122     checkNotNull(iterable);
123     this.iterableDelegate = Optional.fromNullable(this != iterable ? iterable : null);
124   }
125 
126   private Iterable<E> getDelegate() {
127     return iterableDelegate.or(this);
128   }
129 
130   /**
131    * Returns a fluent iterable that wraps {@code iterable}, or {@code iterable} itself if it is
132    * already a {@code FluentIterable}.
133    *
134    * <p><b>{@code Stream} equivalent:</b> {@link Collection#stream} if {@code iterable} is a
135    * {@link Collection}; {@link Streams#stream(Iterable)} otherwise.
136    */
137   public static <E> FluentIterable<E> from(final Iterable<E> iterable) {
138     return (iterable instanceof FluentIterable)
139         ? (FluentIterable<E>) iterable
140         : new FluentIterable<E>(iterable) {
141           @Override
142           public Iterator<E> iterator() {
143             return iterable.iterator();
144           }
145         };
146   }
147 
148   /**
149    * Returns a fluent iterable containing {@code elements} in the specified order.
150    *
151    * <p>The returned iterable is an unmodifiable view of the input array.
152    *
153    * <p><b>{@code Stream} equivalent:</b> {@link java.util.stream.Stream#of(Object[])
154    * Stream.of(T...)}.
155    *
156    * @since 20.0 (since 18.0 as an overload of {@code of})
157    */
158   @Beta
159   public static <E> FluentIterable<E> from(E[] elements) {
160     return from(Arrays.asList(elements));
161   }
162 
163   /**
164    * Construct a fluent iterable from another fluent iterable. This is obviously never necessary,
165    * but is intended to help call out cases where one migration from {@code Iterable} to
166    * {@code FluentIterable} has obviated the need to explicitly convert to a {@code FluentIterable}.
167    *
168    * @deprecated instances of {@code FluentIterable} don't need to be converted to
169    *     {@code FluentIterable}
170    */
171   @Deprecated
172   public static <E> FluentIterable<E> from(FluentIterable<E> iterable) {
173     return checkNotNull(iterable);
174   }
175 
176   /**
177    * Returns a fluent iterable that combines two iterables. The returned iterable has an iterator
178    * that traverses the elements in {@code a}, followed by the elements in {@code b}. The source
179    * iterators are not polled until necessary.
180    *
181    * <p>The returned iterable's iterator supports {@code remove()} when the corresponding input
182    * iterator supports it.
183    *
184    * <p><b>{@code Stream} equivalent:</b> {@link Stream#concat}.
185    *
186    * @since 20.0
187    */
188   @Beta
189   public static <T> FluentIterable<T> concat(Iterable<? extends T> a, Iterable<? extends T> b) {
190     return concatNoDefensiveCopy(a, b);
191   }
192 
193   /**
194    * Returns a fluent iterable that combines three iterables. The returned iterable has an iterator
195    * that traverses the elements in {@code a}, followed by the elements in {@code b}, followed by
196    * the elements in {@code c}. The source iterators are not polled until necessary.
197    *
198    * <p>The returned iterable's iterator supports {@code remove()} when the corresponding input
199    * iterator supports it.
200    *
201    * <p><b>{@code Stream} equivalent:</b> use nested calls to {@link Stream#concat}, or see the
202    * advice in {@link #concat(Iterable...)}.
203    *
204    * @since 20.0
205    */
206   @Beta
207   public static <T> FluentIterable<T> concat(
208       Iterable<? extends T> a, Iterable<? extends T> b, Iterable<? extends T> c) {
209     return concatNoDefensiveCopy(a, b, c);
210   }
211 
212   /**
213    * Returns a fluent iterable that combines four iterables. The returned iterable has an iterator
214    * that traverses the elements in {@code a}, followed by the elements in {@code b}, followed by
215    * the elements in {@code c}, followed by the elements in {@code d}. The source iterators are not
216    * polled until necessary.
217    *
218    * <p>The returned iterable's iterator supports {@code remove()} when the corresponding input
219    * iterator supports it.
220    *
221    * <p><b>{@code Stream} equivalent:</b> use nested calls to {@link Stream#concat}, or see the
222    * advice in {@link #concat(Iterable...)}.
223    *
224    * @since 20.0
225    */
226   @Beta
227   public static <T> FluentIterable<T> concat(
228       Iterable<? extends T> a,
229       Iterable<? extends T> b,
230       Iterable<? extends T> c,
231       Iterable<? extends T> d) {
232     return concatNoDefensiveCopy(a, b, c, d);
233   }
234 
235   /**
236    * Returns a fluent iterable that combines several iterables. The returned iterable has an
237    * iterator that traverses the elements of each iterable in {@code inputs}. The input iterators
238    * are not polled until necessary.
239    *
240    * <p>The returned iterable's iterator supports {@code remove()} when the corresponding input
241    * iterator supports it.
242    *
243    * <p><b>{@code Stream} equivalent:</b> to concatenate an arbitrary number of streams, use {@code
244    * Stream.of(stream1, stream2, ...).flatMap(s -> s)}. If the sources are iterables, use {@code
245    * Stream.of(iter1, iter2, ...).flatMap(Streams::stream)}.
246    *
247    * @throws NullPointerException if any of the provided iterables is {@code null}
248    * @since 20.0
249    */
250   @Beta
251   public static <T> FluentIterable<T> concat(Iterable<? extends T>... inputs) {
252     return concatNoDefensiveCopy(Arrays.copyOf(inputs, inputs.length));
253   }
254 
255   /** Concatenates a varargs array of iterables without making a defensive copy of the array. */
256   private static <T> FluentIterable<T> concatNoDefensiveCopy(
257       final Iterable<? extends T>... inputs) {
258     for (Iterable<? extends T> input : inputs) {
259       checkNotNull(input);
260     }
261     return new FluentIterable<T>() {
262       @Override
263       public Iterator<T> iterator() {
264         return Iterators.concat(
265             /* lazily generate the iterators on each input only as needed */
266             new AbstractIndexedListIterator<Iterator<? extends T>>(inputs.length) {
267               @Override
268               public Iterator<? extends T> get(int i) {
269                 return inputs[i].iterator();
270               }
271             });
272       }
273     };
274   }
275 
276   /**
277    * Returns a fluent iterable that combines several iterables. The returned iterable has an
278    * iterator that traverses the elements of each iterable in {@code inputs}. The input iterators
279    * are not polled until necessary.
280    *
281    * <p>The returned iterable's iterator supports {@code remove()} when the corresponding input
282    * iterator supports it. The methods of the returned iterable may throw {@code
283    * NullPointerException} if any of the input iterators is {@code null}.
284    *
285    * <p><b>{@code Stream} equivalent:</b> {@code streamOfStreams.flatMap(s -> s)} or {@code
286    * streamOfIterables.flatMap(Streams::stream)}. (See {@link Streams#stream}.)
287    *
288    * @since 20.0
289    */
290   @Beta
291   public static <T> FluentIterable<T> concat(
292       final Iterable<? extends Iterable<? extends T>> inputs) {
293     checkNotNull(inputs);
294     return new FluentIterable<T>() {
295       @Override
296       public Iterator<T> iterator() {
297         return Iterators.concat(Iterators.transform(inputs.iterator(), Iterables.<T>toIterator()));
298       }
299     };
300   }
301 
302   /**
303    * Returns a fluent iterable containing no elements.
304    *
305    * <p><b>{@code Stream} equivalent:</b> {@link Stream#empty}.
306    *
307    * @since 20.0
308    */
309   @Beta
310   public static <E> FluentIterable<E> of() {
311     return FluentIterable.from(ImmutableList.<E>of());
312   }
313 
314   /**
315    * Returns a fluent iterable containing the specified elements in order.
316    *
317    * <p><b>{@code Stream} equivalent:</b> {@link java.util.stream.Stream#of(Object[])
318    * Stream.of(T...)}.
319    *
320    * @since 20.0
321    */
322   @Beta
323   public static <E> FluentIterable<E> of(@Nullable E element, E... elements) {
324     return from(Lists.asList(element, elements));
325   }
326 
327   /**
328    * Returns a string representation of this fluent iterable, with the format {@code [e1, e2, ...,
329    * en]}.
330    *
331    * <p><b>{@code Stream} equivalent:</b> {@code stream.collect(Collectors.joining(", ", "[", "]"))}
332    * or (less efficiently) {@code stream.collect(Collectors.toList()).toString()}.
333    */
334   @Override
335   public String toString() {
336     return Iterables.toString(getDelegate());
337   }
338 
339   /**
340    * Returns the number of elements in this fluent iterable.
341    *
342    * <p><b>{@code Stream} equivalent:</b> {@link Stream#count}.
343    */
344   public final int size() {
345     return Iterables.size(getDelegate());
346   }
347 
348   /**
349    * Returns {@code true} if this fluent iterable contains any object for which
350    * {@code equals(target)} is true.
351    *
352    * <p><b>{@code Stream} equivalent:</b> {@code stream.anyMatch(Predicate.isEqual(target))}.
353    */
354   public final boolean contains(@Nullable Object target) {
355     return Iterables.contains(getDelegate(), target);
356   }
357 
358   /**
359    * Returns a fluent iterable whose {@code Iterator} cycles indefinitely over the elements of this
360    * fluent iterable.
361    *
362    * <p>That iterator supports {@code remove()} if {@code iterable.iterator()} does. After
363    * {@code remove()} is called, subsequent cycles omit the removed element, which is no longer in
364    * this fluent iterable. The iterator's {@code hasNext()} method returns {@code true} until this
365    * fluent iterable is empty.
366    *
367    * <p><b>Warning:</b> Typical uses of the resulting iterator may produce an infinite loop. You
368    * should use an explicit {@code break} or be certain that you will eventually remove all the
369    * elements.
370    *
371    * <p><b>{@code Stream} equivalent:</b> if the source iterable has only a single element {@code
372    * e}, use {@code Stream.generate(() -> e)}. Otherwise, collect your stream into a collection and
373    * use {@code Stream.generate(() -> collection).flatMap(Collection::stream)}.
374    */
375   public final FluentIterable<E> cycle() {
376     return from(Iterables.cycle(getDelegate()));
377   }
378 
379   /**
380    * Returns a fluent iterable whose iterators traverse first the elements of this fluent iterable,
381    * followed by those of {@code other}. The iterators are not polled until necessary.
382    *
383    * <p>The returned iterable's {@code Iterator} supports {@code remove()} when the corresponding
384    * {@code Iterator} supports it.
385    *
386    * <p><b>{@code Stream} equivalent:</b> {@link Stream#concat}.
387    *
388    * @since 18.0
389    */
390   @Beta
391   public final FluentIterable<E> append(Iterable<? extends E> other) {
392     return FluentIterable.concat(getDelegate(), other);
393   }
394 
395   /**
396    * Returns a fluent iterable whose iterators traverse first the elements of this fluent iterable,
397    * followed by {@code elements}.
398    *
399    * <p><b>{@code Stream} equivalent:</b> {@code Stream.concat(thisStream, Stream.of(elements))}.
400    *
401    * @since 18.0
402    */
403   @Beta
404   public final FluentIterable<E> append(E... elements) {
405     return FluentIterable.concat(getDelegate(), Arrays.asList(elements));
406   }
407 
408   /**
409    * Returns the elements from this fluent iterable that satisfy a predicate. The resulting fluent
410    * iterable's iterator does not support {@code remove()}.
411    *
412    * <p><b>{@code Stream} equivalent:</b> {@link Stream#filter} (same).
413    */
414   public final FluentIterable<E> filter(Predicate<? super E> predicate) {
415     return from(Iterables.filter(getDelegate(), predicate));
416   }
417 
418   /**
419    * Returns the elements from this fluent iterable that are instances of class {@code type}.
420    *
421    * <p><b>{@code Stream} equivalent:</b> {@code stream.filter(type::isInstance).map(type::cast)}.
422    * This does perform a little more work than necessary, so another option is to insert an
423    * unchecked cast at some later point:
424    *
425    * <pre>
426    * {@code @SuppressWarnings("unchecked") // safe because of ::isInstance check
427    * ImmutableList<NewType> result =
428    *     (ImmutableList) stream.filter(NewType.class::isInstance).collect(toImmutableList());}
429    * </pre>
430    */
431   @GwtIncompatible // Class.isInstance
432   public final <T> FluentIterable<T> filter(Class<T> type) {
433     return from(Iterables.filter(getDelegate(), type));
434   }
435 
436   /**
437    * Returns {@code true} if any element in this fluent iterable satisfies the predicate.
438    *
439    * <p><b>{@code Stream} equivalent:</b> {@link Stream#anyMatch} (same).
440    */
441   public final boolean anyMatch(Predicate<? super E> predicate) {
442     return Iterables.any(getDelegate(), predicate);
443   }
444 
445   /**
446    * Returns {@code true} if every element in this fluent iterable satisfies the predicate. If this
447    * fluent iterable is empty, {@code true} is returned.
448    *
449    * <p><b>{@code Stream} equivalent:</b> {@link Stream#allMatch} (same).
450    */
451   public final boolean allMatch(Predicate<? super E> predicate) {
452     return Iterables.all(getDelegate(), predicate);
453   }
454 
455   /**
456    * Returns an {@link Optional} containing the first element in this fluent iterable that satisfies
457    * the given predicate, if such an element exists.
458    *
459    * <p><b>Warning:</b> avoid using a {@code predicate} that matches {@code null}. If {@code null}
460    * is matched in this fluent iterable, a {@link NullPointerException} will be thrown.
461    *
462    * <p><b>{@code Stream} equivalent:</b> {@code stream.filter(predicate).findFirst()}.
463    */
464   public final Optional<E> firstMatch(Predicate<? super E> predicate) {
465     return Iterables.tryFind(getDelegate(), predicate);
466   }
467 
468   /**
469    * Returns a fluent iterable that applies {@code function} to each element of this fluent
470    * iterable.
471    *
472    * <p>The returned fluent iterable's iterator supports {@code remove()} if this iterable's
473    * iterator does. After a successful {@code remove()} call, this fluent iterable no longer
474    * contains the corresponding element.
475    *
476    * <p><b>{@code Stream} equivalent:</b> {@link Stream#map}.
477    */
478   public final <T> FluentIterable<T> transform(Function<? super E, T> function) {
479     return from(Iterables.transform(getDelegate(), function));
480   }
481 
482   /**
483    * Applies {@code function} to each element of this fluent iterable and returns a fluent iterable
484    * with the concatenated combination of results. {@code function} returns an Iterable of results.
485    *
486    * <p>The returned fluent iterable's iterator supports {@code remove()} if this function-returned
487    * iterables' iterator does. After a successful {@code remove()} call, the returned fluent
488    * iterable no longer contains the corresponding element.
489    *
490    * <p><b>{@code Stream} equivalent:</b> {@link Stream#flatMap} (using a function that produces
491    * streams, not iterables).
492    *
493    * @since 13.0 (required {@code Function<E, Iterable<T>>} until 14.0)
494    */
495   public <T> FluentIterable<T> transformAndConcat(
496       Function<? super E, ? extends Iterable<? extends T>> function) {
497     return FluentIterable.concat(transform(function));
498   }
499 
500   /**
501    * Returns an {@link Optional} containing the first element in this fluent iterable. If the
502    * iterable is empty, {@code Optional.absent()} is returned.
503    *
504    * <p><b>{@code Stream} equivalent:</b> if the goal is to obtain any element, {@link
505    * Stream#findAny}; if it must specifically be the <i>first</i> element, {@code Stream#findFirst}.
506    *
507    * @throws NullPointerException if the first element is null; if this is a possibility, use {@code
508    *     iterator().next()} or {@link Iterables#getFirst} instead.
509    */
510   public final Optional<E> first() {
511     Iterator<E> iterator = getDelegate().iterator();
512     return iterator.hasNext() ? Optional.of(iterator.next()) : Optional.<E>absent();
513   }
514 
515   /**
516    * Returns an {@link Optional} containing the last element in this fluent iterable. If the
517    * iterable is empty, {@code Optional.absent()} is returned. If the underlying {@code iterable}
518    * is a {@link List} with {@link java.util.RandomAccess} support, then this operation is
519    * guaranteed to be {@code O(1)}.
520    *
521    * <p><b>{@code Stream} equivalent:</b> {@code stream.reduce((a, b) -> b)}.
522    *
523    * @throws NullPointerException if the last element is null; if this is a possibility, use
524    *     {@link Iterables#getLast} instead.
525    */
526   public final Optional<E> last() {
527     // Iterables#getLast was inlined here so we don't have to throw/catch a NSEE
528 
529     // TODO(kevinb): Support a concurrently modified collection?
530     Iterable<E> iterable = getDelegate();
531     if (iterable instanceof List) {
532       List<E> list = (List<E>) iterable;
533       if (list.isEmpty()) {
534         return Optional.absent();
535       }
536       return Optional.of(list.get(list.size() - 1));
537     }
538     Iterator<E> iterator = iterable.iterator();
539     if (!iterator.hasNext()) {
540       return Optional.absent();
541     }
542 
543     /*
544      * TODO(kevinb): consider whether this "optimization" is worthwhile. Users with SortedSets tend
545      * to know they are SortedSets and probably would not call this method.
546      */
547     if (iterable instanceof SortedSet) {
548       SortedSet<E> sortedSet = (SortedSet<E>) iterable;
549       return Optional.of(sortedSet.last());
550     }
551 
552     while (true) {
553       E current = iterator.next();
554       if (!iterator.hasNext()) {
555         return Optional.of(current);
556       }
557     }
558   }
559 
560   /**
561    * Returns a view of this fluent iterable that skips its first {@code numberToSkip} elements. If
562    * this fluent iterable contains fewer than {@code numberToSkip} elements, the returned fluent
563    * iterable skips all of its elements.
564    *
565    * <p>Modifications to this fluent iterable before a call to {@code iterator()} are reflected in
566    * the returned fluent iterable. That is, the its iterator skips the first {@code numberToSkip}
567    * elements that exist when the iterator is created, not when {@code skip()} is called.
568    *
569    * <p>The returned fluent iterable's iterator supports {@code remove()} if the {@code Iterator} of
570    * this fluent iterable supports it. Note that it is <i>not</i> possible to delete the last
571    * skipped element by immediately calling {@code remove()} on the returned fluent iterable's
572    * iterator, as the {@code Iterator} contract states that a call to {@code * remove()} before a
573    * call to {@code next()} will throw an {@link IllegalStateException}.
574    *
575    * <p><b>{@code Stream} equivalent:</b> {@link Stream#skip} (same).
576    */
577   public final FluentIterable<E> skip(int numberToSkip) {
578     return from(Iterables.skip(getDelegate(), numberToSkip));
579   }
580 
581   /**
582    * Creates a fluent iterable with the first {@code size} elements of this fluent iterable. If this
583    * fluent iterable does not contain that many elements, the returned fluent iterable will have the
584    * same behavior as this fluent iterable. The returned fluent iterable's iterator supports {@code
585    * remove()} if this fluent iterable's iterator does.
586    *
587    * <p><b>{@code Stream} equivalent:</b> {@link Stream#limit} (same).
588    *
589    * @param maxSize the maximum number of elements in the returned fluent iterable
590    * @throws IllegalArgumentException if {@code size} is negative
591    */
592   public final FluentIterable<E> limit(int maxSize) {
593     return from(Iterables.limit(getDelegate(), maxSize));
594   }
595 
596   /**
597    * Determines whether this fluent iterable is empty.
598    *
599    * <p><b>{@code Stream} equivalent:</b> {@code !stream.findAny().isPresent()}.
600    */
601   public final boolean isEmpty() {
602     return !getDelegate().iterator().hasNext();
603   }
604 
605   /**
606    * Returns an {@code ImmutableList} containing all of the elements from this fluent iterable in
607    * proper sequence.
608    *
609    * <p><b>{@code Stream} equivalent:</b> pass {@link ImmutableList#toImmutableList} to {@code
610    * stream.collect()}.
611    *
612    * @throws NullPointerException if any element is {@code null}
613    * @since 14.0 (since 12.0 as {@code toImmutableList()}).
614    */
615   public final ImmutableList<E> toList() {
616     return ImmutableList.copyOf(getDelegate());
617   }
618 
619   /**
620    * Returns an {@code ImmutableList} containing all of the elements from this {@code
621    * FluentIterable} in the order specified by {@code comparator}. To produce an {@code
622    * ImmutableList} sorted by its natural ordering, use {@code toSortedList(Ordering.natural())}.
623    *
624    * <p><b>{@code Stream} equivalent:</b> pass {@link ImmutableList#toImmutableList} to {@code
625    * stream.sorted(comparator).collect()}.
626    *
627    * @param comparator the function by which to sort list elements
628    * @throws NullPointerException if any element of this iterable is {@code null}
629    * @since 14.0 (since 13.0 as {@code toSortedImmutableList()}).
630    */
631   public final ImmutableList<E> toSortedList(Comparator<? super E> comparator) {
632     return Ordering.from(comparator).immutableSortedCopy(getDelegate());
633   }
634 
635   /**
636    * Returns an {@code ImmutableSet} containing all of the elements from this fluent iterable with
637    * duplicates removed.
638    *
639    * <p><b>{@code Stream} equivalent:</b> pass {@link ImmutableSet#toImmutableSet} to {@code
640    * stream.collect()}.
641    *
642    * @throws NullPointerException if any element is {@code null}
643    * @since 14.0 (since 12.0 as {@code toImmutableSet()}).
644    */
645   public final ImmutableSet<E> toSet() {
646     return ImmutableSet.copyOf(getDelegate());
647   }
648 
649   /**
650    * Returns an {@code ImmutableSortedSet} containing all of the elements from this {@code
651    * FluentIterable} in the order specified by {@code comparator}, with duplicates (determined by
652    * {@code comparator.compare(x, y) == 0}) removed. To produce an {@code ImmutableSortedSet} sorted
653    * by its natural ordering, use {@code toSortedSet(Ordering.natural())}.
654    *
655    * <p><b>{@code Stream} equivalent:</b> pass {@link
656    * ImmutableSortedSet#toImmutableSortedSet} to {@code stream.collect()}.
657    *
658    * @param comparator the function by which to sort set elements
659    * @throws NullPointerException if any element of this iterable is {@code null}
660    * @since 14.0 (since 12.0 as {@code toImmutableSortedSet()}).
661    */
662   public final ImmutableSortedSet<E> toSortedSet(Comparator<? super E> comparator) {
663     return ImmutableSortedSet.copyOf(comparator, getDelegate());
664   }
665 
666   /**
667    * Returns an {@code ImmutableMultiset} containing all of the elements from this fluent iterable.
668    *
669    * <p><b>{@code Stream} equivalent:</b> pass {@link ImmutableMultiset#toImmutableMultiset} to
670    * {@code
671    * stream.collect()}.
672    *
673    * @throws NullPointerException if any element is null
674    * @since 19.0
675    */
676   public final ImmutableMultiset<E> toMultiset() {
677     return ImmutableMultiset.copyOf(getDelegate());
678   }
679 
680   /**
681    * Returns an immutable map whose keys are the distinct elements of this {@code FluentIterable}
682    * and whose value for each key was computed by {@code valueFunction}. The map's iteration order
683    * is the order of the first appearance of each key in this iterable.
684    *
685    * <p>When there are multiple instances of a key in this iterable, it is unspecified whether
686    * {@code valueFunction} will be applied to more than one instance of that key and, if it is,
687    * which result will be mapped to that key in the returned map.
688    *
689    * <p><b>{@code Stream} equivalent:</b> {@code
690    * stream.collect(ImmutableMap.toImmutableMap(k -> k, valueFunction))}.
691    *
692    * @throws NullPointerException if any element of this iterable is {@code null}, or if {@code
693    *     valueFunction} produces {@code null} for any key
694    * @since 14.0
695    */
696   public final <V> ImmutableMap<E, V> toMap(Function<? super E, V> valueFunction) {
697     return Maps.toMap(getDelegate(), valueFunction);
698   }
699 
700   /**
701    * Creates an index {@code ImmutableListMultimap} that contains the results of applying a
702    * specified function to each item in this {@code FluentIterable} of values. Each element of this
703    * iterable will be stored as a value in the resulting multimap, yielding a multimap with the same
704    * size as this iterable. The key used to store that value in the multimap will be the result of
705    * calling the function on that value. The resulting multimap is created as an immutable snapshot.
706    * In the returned multimap, keys appear in the order they are first encountered, and the values
707    * corresponding to each key appear in the same order as they are encountered.
708    *
709    * <p><b>{@code Stream} equivalent:</b> {@code stream.collect(Collectors.groupingBy(keyFunction))}
710    * behaves similarly, but returns a mutable {@code Map<K, List<E>>} instead, and may not preserve
711    * the order of entries).
712    *
713    * @param keyFunction the function used to produce the key for each value
714    * @throws NullPointerException if any element of this iterable is {@code null}, or if {@code
715    *     keyFunction} produces {@code null} for any key
716    * @since 14.0
717    */
718   public final <K> ImmutableListMultimap<K, E> index(Function<? super E, K> keyFunction) {
719     return Multimaps.index(getDelegate(), keyFunction);
720   }
721 
722   /**
723    * Returns a map with the contents of this {@code FluentIterable} as its {@code values}, indexed
724    * by keys derived from those values. In other words, each input value produces an entry in the
725    * map whose key is the result of applying {@code keyFunction} to that value. These entries appear
726    * in the same order as they appeared in this fluent iterable. Example usage:
727    *
728    * <pre>{@code
729    * Color red = new Color("red", 255, 0, 0);
730    * ...
731    * FluentIterable<Color> allColors = FluentIterable.from(ImmutableSet.of(red, green, blue));
732    *
733    * Map<String, Color> colorForName = allColors.uniqueIndex(toStringFunction());
734    * assertThat(colorForName).containsEntry("red", red);
735    * }</pre>
736    *
737    * <p>If your index may associate multiple values with each key, use {@link #index(Function)
738    * index}.
739    *
740    * <p><b>{@code Stream} equivalent:</b> {@code
741    * stream.collect(ImmutableMap.toImmutableMap(keyFunction, v -> v))}.
742    *
743    * @param keyFunction the function used to produce the key for each value
744    * @return a map mapping the result of evaluating the function {@code keyFunction} on each value
745    *     in this fluent iterable to that value
746    * @throws IllegalArgumentException if {@code keyFunction} produces the same key for more than one
747    *     value in this fluent iterable
748    * @throws NullPointerException if any element of this iterable is {@code null}, or if {@code
749    *     keyFunction} produces {@code null} for any key
750    * @since 14.0
751    */
752   public final <K> ImmutableMap<K, E> uniqueIndex(Function<? super E, K> keyFunction) {
753     return Maps.uniqueIndex(getDelegate(), keyFunction);
754   }
755 
756   /**
757    * Returns an array containing all of the elements from this fluent iterable in iteration order.
758    *
759    * <p><b>{@code Stream} equivalent:</b> if an object array is acceptable, use
760    * {@code stream.toArray()}; if {@code type} is a class literal such as {@code MyType.class}, use
761    * {@code stream.toArray(MyType[]::new)}. Otherwise use {@code stream.toArray(
762    * len -> (E[]) Array.newInstance(type, len))}.
763    *
764    * @param type the type of the elements
765    * @return a newly-allocated array into which all the elements of this fluent iterable have been
766    *     copied
767    */
768   @GwtIncompatible // Array.newArray(Class, int)
769   public final E[] toArray(Class<E> type) {
770     return Iterables.toArray(getDelegate(), type);
771   }
772 
773   /**
774    * Copies all the elements from this fluent iterable to {@code collection}. This is equivalent to
775    * calling {@code Iterables.addAll(collection, this)}.
776    *
777    * <p><b>{@code Stream} equivalent:</b> {@code stream.forEachOrdered(collection::add)} or
778    * {@code stream.forEach(collection::add)}.
779    *
780    * @param collection the collection to copy elements to
781    * @return {@code collection}, for convenience
782    * @since 14.0
783    */
784   @CanIgnoreReturnValue
785   public final <C extends Collection<? super E>> C copyInto(C collection) {
786     checkNotNull(collection);
787     Iterable<E> iterable = getDelegate();
788     if (iterable instanceof Collection) {
789       collection.addAll(Collections2.cast(iterable));
790     } else {
791       for (E item : iterable) {
792         collection.add(item);
793       }
794     }
795     return collection;
796   }
797 
798   /**
799    * Returns a {@link String} containing all of the elements of this fluent iterable joined with
800    * {@code joiner}.
801    *
802    * <p><b>{@code Stream} equivalent:</b> {@code joiner.join(stream.iterator())}, or, if you are not
803    * using any optional {@code Joiner} features,
804    * {@code stream.collect(Collectors.joining(delimiter)}.
805    *
806    * @since 18.0
807    */
808   @Beta
809   public final String join(Joiner joiner) {
810     return joiner.join(this);
811   }
812 
813   /**
814    * Returns the element at the specified position in this fluent iterable.
815    *
816    * <p><b>{@code Stream} equivalent:</b> {@code stream.skip(position).findFirst().get()} (but note
817    * that this throws different exception types, and throws an exception if {@code null} would be
818    * returned).
819    *
820    * @param position position of the element to return
821    * @return the element at the specified position in this fluent iterable
822    * @throws IndexOutOfBoundsException if {@code position} is negative or greater than or equal to
823    *     the size of this fluent iterable
824    */
825   // TODO(kevinb): add @Nullable?
826   public final E get(int position) {
827     return Iterables.get(getDelegate(), position);
828   }
829 
830   /**
831    * Returns a stream of this fluent iterable's contents (similar to calling {@link
832    * Collection#stream} on a collection).
833    *
834    * <p><b>Note:</b> the earlier in the chain you can switch to {@code Stream} usage (ideally not
835    * going through {@code FluentIterable} at all), the more performant and idiomatic your code will
836    * be. This method is a transitional aid, to be used only when really necessary.
837    *
838    * @since 21.0
839    */
840   public final Stream<E> stream() {
841     return Streams.stream(getDelegate());
842   }
843 
844   /**
845    * Function that transforms {@code Iterable<E>} into a fluent iterable.
846    */
847   private static class FromIterableFunction<E> implements Function<Iterable<E>, FluentIterable<E>> {
848     @Override
849     public FluentIterable<E> apply(Iterable<E> fromObject) {
850       return FluentIterable.from(fromObject);
851     }
852   }
853 }