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 }