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.Joiner; 026import com.google.common.base.Optional; 027import com.google.common.base.Predicate; 028 029import java.util.Arrays; 030import java.util.Collection; 031import java.util.Comparator; 032import java.util.Iterator; 033import java.util.List; 034import java.util.SortedSet; 035 036import javax.annotation.CheckReturnValue; 037import javax.annotation.Nullable; 038 039/** 040 * {@code FluentIterable} provides a rich interface for manipulating {@code Iterable} instances in a 041 * chained fashion. A {@code FluentIterable} can be created from an {@code Iterable}, or from a set 042 * of elements. The following types of methods are provided on {@code FluentIterable}: 043 * <ul> 044 * <li>chained methods which return a new {@code FluentIterable} based in some way on the contents 045 * of the current one (for example {@link #transform}) 046 * <li>conversion methods which copy the {@code FluentIterable}'s contents into a new collection or 047 * array (for example {@link #toList}) 048 * <li>element extraction methods which facilitate the retrieval of certain elements (for example 049 * {@link #last}) 050 * <li>query methods which answer questions about the {@code FluentIterable}'s contents (for example 051 * {@link #anyMatch}) 052 * </ul> 053 * 054 * <p>Here is an example that merges the lists returned by two separate database calls, transforms 055 * it by invoking {@code toString()} on each element, and returns the first 10 elements as an 056 * {@code ImmutableList}: <pre> {@code 057 * 058 * FluentIterable 059 * .from(database.getClientList()) 060 * .filter(activeInLastMonth()) 061 * .transform(Functions.toStringFunction()) 062 * .limit(10) 063 * .toList();}</pre> 064 * 065 * <p>Anything which can be done using {@code FluentIterable} could be done in a different fashion 066 * (often with {@link Iterables}), however the use of {@code FluentIterable} makes many sets of 067 * operations significantly more concise. 068 * 069 * @author Marcin Mikosik 070 * @since 12.0 071 */ 072@GwtCompatible(emulated = true) 073public abstract class FluentIterable<E> implements Iterable<E> { 074 // We store 'iterable' and use it instead of 'this' to allow Iterables to perform instanceof 075 // checks on the _original_ iterable when FluentIterable.from is used. 076 private final Iterable<E> iterable; 077 078 /** Constructor for use by subclasses. */ 079 protected FluentIterable() { 080 this.iterable = this; 081 } 082 083 FluentIterable(Iterable<E> iterable) { 084 this.iterable = checkNotNull(iterable); 085 } 086 087 /** 088 * Returns a fluent iterable that wraps {@code iterable}, or {@code iterable} itself if it 089 * is already a {@code FluentIterable}. 090 */ 091 public static <E> FluentIterable<E> from(final Iterable<E> iterable) { 092 return (iterable instanceof FluentIterable) ? (FluentIterable<E>) iterable 093 : new FluentIterable<E>(iterable) { 094 @Override 095 public Iterator<E> iterator() { 096 return iterable.iterator(); 097 } 098 }; 099 } 100 101 /** 102 * Construct a fluent iterable from another fluent iterable. This is obviously never necessary, 103 * but is intended to help call out cases where one migration from {@code Iterable} to 104 * {@code FluentIterable} has obviated the need to explicitly convert to a {@code FluentIterable}. 105 * 106 * @deprecated instances of {@code FluentIterable} don't need to be converted to 107 * {@code FluentIterable} 108 */ 109 @Deprecated 110 public static <E> FluentIterable<E> from(FluentIterable<E> iterable) { 111 return checkNotNull(iterable); 112 } 113 114 /** 115 * Returns a fluent iterable containing {@code elements} in the specified order. 116 * 117 * @since 18.0 118 */ 119 @Beta 120 public static <E> FluentIterable<E> of(E[] elements) { 121 return from(Lists.newArrayList(elements)); 122 } 123 124 /** 125 * Returns a string representation of this fluent iterable, with the format 126 * {@code [e1, e2, ..., en]}. 127 */ 128 @Override 129 public String toString() { 130 return Iterables.toString(iterable); 131 } 132 133 /** 134 * Returns the number of elements in this fluent iterable. 135 */ 136 public final int size() { 137 return Iterables.size(iterable); 138 } 139 140 /** 141 * Returns {@code true} if this fluent iterable contains any object for which 142 * {@code equals(element)} is true. 143 */ 144 public final boolean contains(@Nullable Object element) { 145 return Iterables.contains(iterable, element); 146 } 147 148 /** 149 * Returns a fluent iterable whose {@code Iterator} cycles indefinitely over the elements of 150 * this fluent iterable. 151 * 152 * <p>That iterator supports {@code remove()} if {@code iterable.iterator()} does. After 153 * {@code remove()} is called, subsequent cycles omit the removed element, which is no longer in 154 * this fluent iterable. The iterator's {@code hasNext()} method returns {@code true} until 155 * this fluent iterable is empty. 156 * 157 * <p><b>Warning:</b> Typical uses of the resulting iterator may produce an infinite loop. You 158 * should use an explicit {@code break} or be certain that you will eventually remove all the 159 * elements. 160 */ 161 @CheckReturnValue 162 public final FluentIterable<E> cycle() { 163 return from(Iterables.cycle(iterable)); 164 } 165 166 /** 167 * Returns a fluent iterable whose iterators traverse first the elements of this fluent iterable, 168 * followed by those of {@code other}. The iterators are not polled until necessary. 169 * 170 * <p>The returned iterable's {@code Iterator} supports {@code remove()} when the corresponding 171 * {@code Iterator} supports it. 172 * 173 * @since 18.0 174 */ 175 @Beta 176 @CheckReturnValue 177 public final FluentIterable<E> append(Iterable<? extends E> other) { 178 return from(Iterables.concat(iterable, other)); 179 } 180 181 /** 182 * Returns a fluent iterable whose iterators traverse first the elements of this fluent iterable, 183 * followed by {@code elements}. 184 * 185 * @since 18.0 186 */ 187 @Beta 188 @CheckReturnValue 189 public final FluentIterable<E> append(E... elements) { 190 return from(Iterables.concat(iterable, Arrays.asList(elements))); 191 } 192 193 /** 194 * Returns the elements from this fluent iterable that satisfy a predicate. The 195 * resulting fluent iterable's iterator does not support {@code remove()}. 196 */ 197 @CheckReturnValue 198 public final FluentIterable<E> filter(Predicate<? super E> predicate) { 199 return from(Iterables.filter(iterable, predicate)); 200 } 201 202 /** 203 * Returns the elements from this fluent iterable that are instances of class {@code type}. 204 * 205 * @param type the type of elements desired 206 */ 207 @GwtIncompatible("Class.isInstance") 208 @CheckReturnValue 209 public final <T> FluentIterable<T> filter(Class<T> type) { 210 return from(Iterables.filter(iterable, type)); 211 } 212 213 /** 214 * Returns {@code true} if any element in this fluent iterable satisfies the predicate. 215 */ 216 public final boolean anyMatch(Predicate<? super E> predicate) { 217 return Iterables.any(iterable, predicate); 218 } 219 220 /** 221 * Returns {@code true} if every element in this fluent iterable satisfies the predicate. 222 * If this fluent iterable is empty, {@code true} is returned. 223 */ 224 public final boolean allMatch(Predicate<? super E> predicate) { 225 return Iterables.all(iterable, predicate); 226 } 227 228 /** 229 * Returns an {@link Optional} containing the first element in this fluent iterable that 230 * satisfies the given predicate, if such an element exists. 231 * 232 * <p><b>Warning:</b> avoid using a {@code predicate} that matches {@code null}. If {@code null} 233 * is matched in this fluent iterable, a {@link NullPointerException} will be thrown. 234 */ 235 public final Optional<E> firstMatch(Predicate<? super E> predicate) { 236 return Iterables.tryFind(iterable, predicate); 237 } 238 239 /** 240 * Returns a fluent iterable that applies {@code function} to each element of this 241 * fluent iterable. 242 * 243 * <p>The returned fluent iterable's iterator supports {@code remove()} if this iterable's 244 * iterator does. After a successful {@code remove()} call, this fluent iterable no longer 245 * contains the corresponding element. 246 */ 247 public final <T> FluentIterable<T> transform(Function<? super E, T> function) { 248 return from(Iterables.transform(iterable, function)); 249 } 250 251 /** 252 * Applies {@code function} to each element of this fluent iterable and returns 253 * a fluent iterable with the concatenated combination of results. {@code function} 254 * returns an Iterable of results. 255 * 256 * <p>The returned fluent iterable's iterator supports {@code remove()} if this 257 * function-returned iterables' iterator does. After a successful {@code remove()} call, 258 * the returned fluent iterable no longer contains the corresponding element. 259 * 260 * @since 13.0 (required {@code Function<E, Iterable<T>>} until 14.0) 261 */ 262 public <T> FluentIterable<T> transformAndConcat( 263 Function<? super E, ? extends Iterable<? extends T>> function) { 264 return from(Iterables.concat(transform(function))); 265 } 266 267 /** 268 * Returns an {@link Optional} containing the first element in this fluent iterable. 269 * If the iterable is empty, {@code Optional.absent()} is returned. 270 * 271 * @throws NullPointerException if the first element is null; if this is a possibility, use 272 * {@code iterator().next()} or {@link Iterables#getFirst} instead. 273 */ 274 public final Optional<E> first() { 275 Iterator<E> iterator = iterable.iterator(); 276 return iterator.hasNext() 277 ? Optional.of(iterator.next()) 278 : Optional.<E>absent(); 279 } 280 281 /** 282 * Returns an {@link Optional} containing the last element in this fluent iterable. 283 * If the iterable is empty, {@code Optional.absent()} is returned. 284 * 285 * @throws NullPointerException if the last element is null; if this is a possibility, use 286 * {@link Iterables#getLast} instead. 287 */ 288 public final Optional<E> last() { 289 // Iterables#getLast was inlined here so we don't have to throw/catch a NSEE 290 291 // TODO(kevinb): Support a concurrently modified collection? 292 if (iterable instanceof List) { 293 List<E> list = (List<E>) iterable; 294 if (list.isEmpty()) { 295 return Optional.absent(); 296 } 297 return Optional.of(list.get(list.size() - 1)); 298 } 299 Iterator<E> iterator = iterable.iterator(); 300 if (!iterator.hasNext()) { 301 return Optional.absent(); 302 } 303 304 /* 305 * TODO(kevinb): consider whether this "optimization" is worthwhile. Users 306 * with SortedSets tend to know they are SortedSets and probably would not 307 * call this method. 308 */ 309 if (iterable instanceof SortedSet) { 310 SortedSet<E> sortedSet = (SortedSet<E>) iterable; 311 return Optional.of(sortedSet.last()); 312 } 313 314 while (true) { 315 E current = iterator.next(); 316 if (!iterator.hasNext()) { 317 return Optional.of(current); 318 } 319 } 320 } 321 322 /** 323 * Returns a view of this fluent iterable that skips its first {@code numberToSkip} 324 * elements. If this fluent iterable contains fewer than {@code numberToSkip} elements, 325 * the returned fluent iterable skips all of its elements. 326 * 327 * <p>Modifications to this fluent iterable before a call to {@code iterator()} are 328 * reflected in the returned fluent iterable. That is, the its iterator skips the first 329 * {@code numberToSkip} elements that exist when the iterator is created, not when {@code skip()} 330 * is called. 331 * 332 * <p>The returned fluent iterable's iterator supports {@code remove()} if the 333 * {@code Iterator} of this fluent iterable supports it. Note that it is <i>not</i> 334 * possible to delete the last skipped element by immediately calling {@code remove()} on the 335 * returned fluent iterable's iterator, as the {@code Iterator} contract states that a call 336 * to {@code * remove()} before a call to {@code next()} will throw an 337 * {@link IllegalStateException}. 338 */ 339 @CheckReturnValue 340 public final FluentIterable<E> skip(int numberToSkip) { 341 return from(Iterables.skip(iterable, numberToSkip)); 342 } 343 344 /** 345 * Creates a fluent iterable with the first {@code size} elements of this 346 * fluent iterable. If this fluent iterable does not contain that many elements, 347 * the returned fluent iterable will have the same behavior as this fluent iterable. 348 * The returned fluent iterable's iterator supports {@code remove()} if this 349 * fluent iterable's iterator does. 350 * 351 * @param size the maximum number of elements in the returned fluent iterable 352 * @throws IllegalArgumentException if {@code size} is negative 353 */ 354 @CheckReturnValue 355 public final FluentIterable<E> limit(int size) { 356 return from(Iterables.limit(iterable, size)); 357 } 358 359 /** 360 * Determines whether this fluent iterable is empty. 361 */ 362 public final boolean isEmpty() { 363 return !iterable.iterator().hasNext(); 364 } 365 366 /** 367 * Returns an {@code ImmutableList} containing all of the elements from this fluent iterable in 368 * proper sequence. 369 * 370 * @since 14.0 (since 12.0 as {@code toImmutableList()}). 371 */ 372 public final ImmutableList<E> toList() { 373 return ImmutableList.copyOf(iterable); 374 } 375 376 /** 377 * Returns an {@code ImmutableList} containing all of the elements from this {@code 378 * FluentIterable} in the order specified by {@code comparator}. To produce an {@code 379 * ImmutableList} sorted by its natural ordering, use {@code toSortedList(Ordering.natural())}. 380 * 381 * @param comparator the function by which to sort list elements 382 * @throws NullPointerException if any element is null 383 * @since 14.0 (since 13.0 as {@code toSortedImmutableList()}). 384 */ 385 public final ImmutableList<E> toSortedList(Comparator<? super E> comparator) { 386 return Ordering.from(comparator).immutableSortedCopy(iterable); 387 } 388 389 /** 390 * Returns an {@code ImmutableSet} containing all of the elements from this fluent iterable with 391 * duplicates removed. 392 * 393 * @since 14.0 (since 12.0 as {@code toImmutableSet()}). 394 */ 395 public final ImmutableSet<E> toSet() { 396 return ImmutableSet.copyOf(iterable); 397 } 398 399 /** 400 * Returns an {@code ImmutableSortedSet} containing all of the elements from this {@code 401 * FluentIterable} in the order specified by {@code comparator}, with duplicates (determined by 402 * {@code comparator.compare(x, y) == 0}) removed. To produce an {@code ImmutableSortedSet} sorted 403 * by its natural ordering, use {@code toSortedSet(Ordering.natural())}. 404 * 405 * @param comparator the function by which to sort set elements 406 * @throws NullPointerException if any element is null 407 * @since 14.0 (since 12.0 as {@code toImmutableSortedSet()}). 408 */ 409 public final ImmutableSortedSet<E> toSortedSet(Comparator<? super E> comparator) { 410 return ImmutableSortedSet.copyOf(comparator, iterable); 411 } 412 413 /** 414 * Returns an immutable map for which the elements of this {@code FluentIterable} are the keys in 415 * the same order, mapped to values by the given function. If this iterable contains duplicate 416 * elements, the returned map will contain each distinct element once in the order it first 417 * appears. 418 * 419 * @throws NullPointerException if any element of this iterable is {@code null}, or if {@code 420 * valueFunction} produces {@code null} for any key 421 * @since 14.0 422 */ 423 public final <V> ImmutableMap<E, V> toMap(Function<? super E, V> valueFunction) { 424 return Maps.toMap(iterable, valueFunction); 425 } 426 427 /** 428 * Creates an index {@code ImmutableListMultimap} that contains the results of applying a 429 * specified function to each item in this {@code FluentIterable} of values. Each element of this 430 * iterable will be stored as a value in the resulting multimap, yielding a multimap with the same 431 * size as this iterable. The key used to store that value in the multimap will be the result of 432 * calling the function on that value. The resulting multimap is created as an immutable snapshot. 433 * In the returned multimap, keys appear in the order they are first encountered, and the values 434 * corresponding to each key appear in the same order as they are encountered. 435 * 436 * @param keyFunction the function used to produce the key for each value 437 * @throws NullPointerException if any of the following cases is true: 438 * <ul> 439 * <li>{@code keyFunction} is null 440 * <li>An element in this fluent iterable is null 441 * <li>{@code keyFunction} returns {@code null} for any element of this iterable 442 * </ul> 443 * @since 14.0 444 */ 445 public final <K> ImmutableListMultimap<K, E> index(Function<? super E, K> keyFunction) { 446 return Multimaps.index(iterable, keyFunction); 447 } 448 449 /** 450 * Returns an immutable map for which the {@link java.util.Map#values} are the elements of this 451 * {@code FluentIterable} in the given order, and each key is the product of invoking a supplied 452 * function on its corresponding value. 453 * 454 * @param keyFunction the function used to produce the key for each value 455 * @throws IllegalArgumentException if {@code keyFunction} produces the same key for more than one 456 * value in this fluent iterable 457 * @throws NullPointerException if any element of this fluent iterable is null, or if 458 * {@code keyFunction} produces {@code null} for any value 459 * @since 14.0 460 */ 461 public final <K> ImmutableMap<K, E> uniqueIndex(Function<? super E, K> keyFunction) { 462 return Maps.uniqueIndex(iterable, keyFunction); 463 } 464 465 /** 466 * Returns an array containing all of the elements from this fluent iterable in iteration order. 467 * 468 * @param type the type of the elements 469 * @return a newly-allocated array into which all the elements of this fluent iterable have 470 * been copied 471 */ 472 @GwtIncompatible("Array.newArray(Class, int)") 473 public final E[] toArray(Class<E> type) { 474 return Iterables.toArray(iterable, type); 475 } 476 477 /** 478 * Copies all the elements from this fluent iterable to {@code collection}. This is equivalent to 479 * calling {@code Iterables.addAll(collection, this)}. 480 * 481 * @param collection the collection to copy elements to 482 * @return {@code collection}, for convenience 483 * @since 14.0 484 */ 485 public final <C extends Collection<? super E>> C copyInto(C collection) { 486 checkNotNull(collection); 487 if (iterable instanceof Collection) { 488 collection.addAll(Collections2.cast(iterable)); 489 } else { 490 for (E item : iterable) { 491 collection.add(item); 492 } 493 } 494 return collection; 495 } 496 497 /** 498 * Returns a {@link String} containing all of the elements of this fluent iterable joined with 499 * {@code joiner}. 500 * 501 * @since 18.0 502 */ 503 @Beta 504 public final String join(Joiner joiner) { 505 return joiner.join(this); 506 } 507 508 /** 509 * Returns the element at the specified position in this fluent iterable. 510 * 511 * @param position position of the element to return 512 * @return the element at the specified position in this fluent iterable 513 * @throws IndexOutOfBoundsException if {@code position} is negative or greater than or equal to 514 * the size of this fluent iterable 515 */ 516 public final E get(int position) { 517 return Iterables.get(iterable, position); 518 } 519 520 /** 521 * Function that transforms {@code Iterable<E>} into a fluent iterable. 522 */ 523 private static class FromIterableFunction<E> 524 implements Function<Iterable<E>, FluentIterable<E>> { 525 @Override 526 public FluentIterable<E> apply(Iterable<E> fromObject) { 527 return FluentIterable.from(fromObject); 528 } 529 } 530}