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 accepts a list from a database call, filters it based on a predicate, 055 * transforms it by invoking {@code toString()} on each element, and returns the first 10 elements 056 * as an {@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 @CheckReturnValue 092 public static <E> FluentIterable<E> from(final Iterable<E> iterable) { 093 return (iterable instanceof FluentIterable) 094 ? (FluentIterable<E>) iterable 095 : new FluentIterable<E>(iterable) { 096 @Override 097 public Iterator<E> iterator() { 098 return iterable.iterator(); 099 } 100 }; 101 } 102 103 /** 104 * Construct a fluent iterable from another fluent iterable. This is obviously never necessary, 105 * but is intended to help call out cases where one migration from {@code Iterable} to 106 * {@code FluentIterable} has obviated the need to explicitly convert to a {@code FluentIterable}. 107 * 108 * @deprecated instances of {@code FluentIterable} don't need to be converted to 109 * {@code FluentIterable} 110 */ 111 @Deprecated 112 @CheckReturnValue 113 public static <E> FluentIterable<E> from(FluentIterable<E> iterable) { 114 return checkNotNull(iterable); 115 } 116 117 /** 118 * Returns a fluent iterable containing {@code elements} in the specified order. 119 * 120 * @since 18.0 121 */ 122 @Beta 123 @CheckReturnValue 124 public static <E> FluentIterable<E> of(E[] elements) { 125 return from(Lists.newArrayList(elements)); 126 } 127 128 /** 129 * Returns a string representation of this fluent iterable, with the format 130 * {@code [e1, e2, ..., en]}. 131 */ 132 @Override 133 @CheckReturnValue 134 public String toString() { 135 return Iterables.toString(iterable); 136 } 137 138 /** 139 * Returns the number of elements in this fluent iterable. 140 */ 141 @CheckReturnValue 142 public final int size() { 143 return Iterables.size(iterable); 144 } 145 146 /** 147 * Returns {@code true} if this fluent iterable contains any object for which 148 * {@code equals(element)} is true. 149 */ 150 @CheckReturnValue 151 public final boolean contains(@Nullable Object element) { 152 return Iterables.contains(iterable, element); 153 } 154 155 /** 156 * Returns a fluent iterable whose {@code Iterator} cycles indefinitely over the elements of 157 * this fluent iterable. 158 * 159 * <p>That iterator supports {@code remove()} if {@code iterable.iterator()} does. After 160 * {@code remove()} is called, subsequent cycles omit the removed element, which is no longer in 161 * this fluent iterable. The iterator's {@code hasNext()} method returns {@code true} until 162 * this fluent iterable is empty. 163 * 164 * <p><b>Warning:</b> Typical uses of the resulting iterator may produce an infinite loop. You 165 * should use an explicit {@code break} or be certain that you will eventually remove all the 166 * elements. 167 */ 168 @CheckReturnValue 169 public final FluentIterable<E> cycle() { 170 return from(Iterables.cycle(iterable)); 171 } 172 173 /** 174 * Returns a fluent iterable whose iterators traverse first the elements of this fluent iterable, 175 * followed by those of {@code other}. The iterators are not polled until necessary. 176 * 177 * <p>The returned iterable's {@code Iterator} supports {@code remove()} when the corresponding 178 * {@code Iterator} supports it. 179 * 180 * @since 18.0 181 */ 182 @Beta 183 @CheckReturnValue 184 public final FluentIterable<E> append(Iterable<? extends E> other) { 185 return from(Iterables.concat(iterable, other)); 186 } 187 188 /** 189 * Returns a fluent iterable whose iterators traverse first the elements of this fluent iterable, 190 * followed by {@code elements}. 191 * 192 * @since 18.0 193 */ 194 @Beta 195 @CheckReturnValue 196 public final FluentIterable<E> append(E... elements) { 197 return from(Iterables.concat(iterable, Arrays.asList(elements))); 198 } 199 200 /** 201 * Returns the elements from this fluent iterable that satisfy a predicate. The 202 * resulting fluent iterable's iterator does not support {@code remove()}. 203 */ 204 @CheckReturnValue 205 public final FluentIterable<E> filter(Predicate<? super E> predicate) { 206 return from(Iterables.filter(iterable, predicate)); 207 } 208 209 /** 210 * Returns the elements from this fluent iterable that are instances of class {@code type}. 211 * 212 * @param type the type of elements desired 213 */ 214 @GwtIncompatible("Class.isInstance") 215 @CheckReturnValue 216 public final <T> FluentIterable<T> filter(Class<T> type) { 217 return from(Iterables.filter(iterable, type)); 218 } 219 220 /** 221 * Returns {@code true} if any element in this fluent iterable satisfies the predicate. 222 */ 223 @CheckReturnValue 224 public final boolean anyMatch(Predicate<? super E> predicate) { 225 return Iterables.any(iterable, predicate); 226 } 227 228 /** 229 * Returns {@code true} if every element in this fluent iterable satisfies the predicate. 230 * If this fluent iterable is empty, {@code true} is returned. 231 */ 232 @CheckReturnValue 233 public final boolean allMatch(Predicate<? super E> predicate) { 234 return Iterables.all(iterable, predicate); 235 } 236 237 /** 238 * Returns an {@link Optional} containing the first element in this fluent iterable that 239 * satisfies the given predicate, if such an element exists. 240 * 241 * <p><b>Warning:</b> avoid using a {@code predicate} that matches {@code null}. If {@code null} 242 * is matched in this fluent iterable, a {@link NullPointerException} will be thrown. 243 */ 244 @CheckReturnValue 245 public final Optional<E> firstMatch(Predicate<? super E> predicate) { 246 return Iterables.tryFind(iterable, predicate); 247 } 248 249 /** 250 * Returns a fluent iterable that applies {@code function} to each element of this 251 * fluent iterable. 252 * 253 * <p>The returned fluent iterable's iterator supports {@code remove()} if this iterable's 254 * iterator does. After a successful {@code remove()} call, this fluent iterable no longer 255 * contains the corresponding element. 256 */ 257 @CheckReturnValue 258 public final <T> FluentIterable<T> transform(Function<? super E, T> function) { 259 return from(Iterables.transform(iterable, function)); 260 } 261 262 /** 263 * Applies {@code function} to each element of this fluent iterable and returns 264 * a fluent iterable with the concatenated combination of results. {@code function} 265 * returns an Iterable of results. 266 * 267 * <p>The returned fluent iterable's iterator supports {@code remove()} if this 268 * function-returned iterables' iterator does. After a successful {@code remove()} call, 269 * the returned fluent iterable no longer contains the corresponding element. 270 * 271 * @since 13.0 (required {@code Function<E, Iterable<T>>} until 14.0) 272 */ 273 @CheckReturnValue 274 public <T> FluentIterable<T> transformAndConcat( 275 Function<? super E, ? extends Iterable<? extends T>> function) { 276 return from(Iterables.concat(transform(function))); 277 } 278 279 /** 280 * Returns an {@link Optional} containing the first element in this fluent iterable. 281 * If the iterable is empty, {@code Optional.absent()} is returned. 282 * 283 * @throws NullPointerException if the first element is null; if this is a possibility, use 284 * {@code iterator().next()} or {@link Iterables#getFirst} instead. 285 */ 286 @CheckReturnValue 287 public final Optional<E> first() { 288 Iterator<E> iterator = iterable.iterator(); 289 return iterator.hasNext() 290 ? Optional.of(iterator.next()) 291 : Optional.<E>absent(); 292 } 293 294 /** 295 * Returns an {@link Optional} containing the last element in this fluent iterable. 296 * If the iterable is empty, {@code Optional.absent()} is returned. 297 * 298 * @throws NullPointerException if the last element is null; if this is a possibility, use 299 * {@link Iterables#getLast} instead. 300 */ 301 @CheckReturnValue 302 public final Optional<E> last() { 303 // Iterables#getLast was inlined here so we don't have to throw/catch a NSEE 304 305 // TODO(kevinb): Support a concurrently modified collection? 306 if (iterable instanceof List) { 307 List<E> list = (List<E>) iterable; 308 if (list.isEmpty()) { 309 return Optional.absent(); 310 } 311 return Optional.of(list.get(list.size() - 1)); 312 } 313 Iterator<E> iterator = iterable.iterator(); 314 if (!iterator.hasNext()) { 315 return Optional.absent(); 316 } 317 318 /* 319 * TODO(kevinb): consider whether this "optimization" is worthwhile. Users 320 * with SortedSets tend to know they are SortedSets and probably would not 321 * call this method. 322 */ 323 if (iterable instanceof SortedSet) { 324 SortedSet<E> sortedSet = (SortedSet<E>) iterable; 325 return Optional.of(sortedSet.last()); 326 } 327 328 while (true) { 329 E current = iterator.next(); 330 if (!iterator.hasNext()) { 331 return Optional.of(current); 332 } 333 } 334 } 335 336 /** 337 * Returns a view of this fluent iterable that skips its first {@code numberToSkip} 338 * elements. If this fluent iterable contains fewer than {@code numberToSkip} elements, 339 * the returned fluent iterable skips all of its elements. 340 * 341 * <p>Modifications to this fluent iterable before a call to {@code iterator()} are 342 * reflected in the returned fluent iterable. That is, the its iterator skips the first 343 * {@code numberToSkip} elements that exist when the iterator is created, not when {@code skip()} 344 * is called. 345 * 346 * <p>The returned fluent iterable's iterator supports {@code remove()} if the 347 * {@code Iterator} of this fluent iterable supports it. Note that it is <i>not</i> 348 * possible to delete the last skipped element by immediately calling {@code remove()} on the 349 * returned fluent iterable's iterator, as the {@code Iterator} contract states that a call 350 * to {@code * remove()} before a call to {@code next()} will throw an 351 * {@link IllegalStateException}. 352 */ 353 @CheckReturnValue 354 public final FluentIterable<E> skip(int numberToSkip) { 355 return from(Iterables.skip(iterable, numberToSkip)); 356 } 357 358 /** 359 * Creates a fluent iterable with the first {@code size} elements of this 360 * fluent iterable. If this fluent iterable does not contain that many elements, 361 * the returned fluent iterable will have the same behavior as this fluent iterable. 362 * The returned fluent iterable's iterator supports {@code remove()} if this 363 * fluent iterable's iterator does. 364 * 365 * @param size the maximum number of elements in the returned fluent iterable 366 * @throws IllegalArgumentException if {@code size} is negative 367 */ 368 @CheckReturnValue 369 public final FluentIterable<E> limit(int size) { 370 return from(Iterables.limit(iterable, size)); 371 } 372 373 /** 374 * Determines whether this fluent iterable is empty. 375 */ 376 @CheckReturnValue 377 public final boolean isEmpty() { 378 return !iterable.iterator().hasNext(); 379 } 380 381 /** 382 * Returns an {@code ImmutableList} containing all of the elements from this fluent iterable in 383 * proper sequence. 384 * 385 * @since 14.0 (since 12.0 as {@code toImmutableList()}). 386 */ 387 @CheckReturnValue 388 public final ImmutableList<E> toList() { 389 return ImmutableList.copyOf(iterable); 390 } 391 392 /** 393 * Returns an {@code ImmutableList} containing all of the elements from this {@code 394 * FluentIterable} in the order specified by {@code comparator}. To produce an {@code 395 * ImmutableList} sorted by its natural ordering, use {@code toSortedList(Ordering.natural())}. 396 * 397 * @param comparator the function by which to sort list elements 398 * @throws NullPointerException if any element is null 399 * @since 14.0 (since 13.0 as {@code toSortedImmutableList()}). 400 */ 401 @CheckReturnValue 402 public final ImmutableList<E> toSortedList(Comparator<? super E> comparator) { 403 return Ordering.from(comparator).immutableSortedCopy(iterable); 404 } 405 406 /** 407 * Returns an {@code ImmutableSet} containing all of the elements from this fluent iterable with 408 * duplicates removed. 409 * 410 * @since 14.0 (since 12.0 as {@code toImmutableSet()}). 411 */ 412 @CheckReturnValue 413 public final ImmutableSet<E> toSet() { 414 return ImmutableSet.copyOf(iterable); 415 } 416 417 /** 418 * Returns an {@code ImmutableSortedSet} containing all of the elements from this {@code 419 * FluentIterable} in the order specified by {@code comparator}, with duplicates (determined by 420 * {@code comparator.compare(x, y) == 0}) removed. To produce an {@code ImmutableSortedSet} sorted 421 * by its natural ordering, use {@code toSortedSet(Ordering.natural())}. 422 * 423 * @param comparator the function by which to sort set elements 424 * @throws NullPointerException if any element is null 425 * @since 14.0 (since 12.0 as {@code toImmutableSortedSet()}). 426 */ 427 @CheckReturnValue 428 public final ImmutableSortedSet<E> toSortedSet(Comparator<? super E> comparator) { 429 return ImmutableSortedSet.copyOf(comparator, iterable); 430 } 431 432 /** 433 * Returns an {@code ImmutableMultiset} containing all of the elements from this fluent iterable. 434 * 435 * @since 19.0 436 */ 437 @CheckReturnValue 438 public final ImmutableMultiset<E> toMultiset() { 439 return ImmutableMultiset.copyOf(iterable); 440 } 441 442 /** 443 * Returns an immutable map whose keys are the distinct elements of this {@code FluentIterable} 444 * and whose value for each key was computed by {@code valueFunction}. The map's iteration order 445 * is the order of the first appearance of each key in this iterable. 446 * 447 * <p>When there are multiple instances of a key in this iterable, it is unspecified whether 448 * {@code valueFunction} will be applied to more than one instance of that key and, if it is, 449 * which result will be mapped to that key in the returned map. 450 * 451 * @throws NullPointerException if any element of this iterable is {@code null}, or if {@code 452 * valueFunction} produces {@code null} for any key 453 * @since 14.0 454 */ 455 @CheckReturnValue 456 public final <V> ImmutableMap<E, V> toMap(Function<? super E, V> valueFunction) { 457 return Maps.toMap(iterable, valueFunction); 458 } 459 460 /** 461 * Creates an index {@code ImmutableListMultimap} that contains the results of applying a 462 * specified function to each item in this {@code FluentIterable} of values. Each element of this 463 * iterable will be stored as a value in the resulting multimap, yielding a multimap with the same 464 * size as this iterable. The key used to store that value in the multimap will be the result of 465 * calling the function on that value. The resulting multimap is created as an immutable snapshot. 466 * In the returned multimap, keys appear in the order they are first encountered, and the values 467 * corresponding to each key appear in the same order as they are encountered. 468 * 469 * @param keyFunction the function used to produce the key for each value 470 * @throws NullPointerException if any of the following cases is true: 471 * <ul> 472 * <li>{@code keyFunction} is null 473 * <li>An element in this fluent iterable is null 474 * <li>{@code keyFunction} returns {@code null} for any element of this iterable 475 * </ul> 476 * @since 14.0 477 */ 478 @CheckReturnValue 479 public final <K> ImmutableListMultimap<K, E> index(Function<? super E, K> keyFunction) { 480 return Multimaps.index(iterable, keyFunction); 481 } 482 483 /** 484 * Returns a map with the contents of this {@code FluentIterable} as its {@code values}, indexed 485 * by keys derived from those values. In other words, each input value produces an entry in the 486 * map whose key is the result of applying {@code keyFunction} to that value. These entries appear 487 * in the same order as they appeared in this fluent iterable. Example usage: 488 * <pre> {@code 489 * 490 * Color red = new Color("red", 255, 0, 0); 491 * ... 492 * FluentIterable<Color> allColors = FluentIterable.from(ImmutableSet.of(red, green, blue)); 493 * 494 * Map<String, Color> colorForName = allColors.uniqueIndex(toStringFunction()); 495 * assertThat(colorForName).containsEntry("red", red);}</pre> 496 * 497 * <p>If your index may associate multiple values with each key, use {@link #index(Function) 498 * index}. 499 * 500 * @param keyFunction the function used to produce the key for each value 501 * @return a map mapping the result of evaluating the function {@code 502 * keyFunction} on each value in this fluent iterable to that value 503 * @throws IllegalArgumentException if {@code keyFunction} produces the same 504 * key for more than one value in this fluent iterable 505 * @throws NullPointerException if any elements of this fluent iterable is null, or 506 * if {@code keyFunction} produces {@code null} for any value 507 * @since 14.0 508 */ 509 @CheckReturnValue 510 public final <K> ImmutableMap<K, E> uniqueIndex(Function<? super E, K> keyFunction) { 511 return Maps.uniqueIndex(iterable, keyFunction); 512 } 513 514 /** 515 * Returns an array containing all of the elements from this fluent iterable in iteration order. 516 * 517 * @param type the type of the elements 518 * @return a newly-allocated array into which all the elements of this fluent iterable have 519 * been copied 520 */ 521 @GwtIncompatible("Array.newArray(Class, int)") 522 @CheckReturnValue 523 public final E[] toArray(Class<E> type) { 524 return Iterables.toArray(iterable, type); 525 } 526 527 /** 528 * Copies all the elements from this fluent iterable to {@code collection}. This is equivalent to 529 * calling {@code Iterables.addAll(collection, this)}. 530 * 531 * @param collection the collection to copy elements to 532 * @return {@code collection}, for convenience 533 * @since 14.0 534 */ 535 public final <C extends Collection<? super E>> C copyInto(C collection) { 536 checkNotNull(collection); 537 if (iterable instanceof Collection) { 538 collection.addAll(Collections2.cast(iterable)); 539 } else { 540 for (E item : iterable) { 541 collection.add(item); 542 } 543 } 544 return collection; 545 } 546 547 /** 548 * Returns a {@link String} containing all of the elements of this fluent iterable joined with 549 * {@code joiner}. 550 * 551 * @since 18.0 552 */ 553 @Beta 554 @CheckReturnValue 555 public final String join(Joiner joiner) { 556 return joiner.join(this); 557 } 558 559 /** 560 * Returns the element at the specified position in this fluent iterable. 561 * 562 * @param position position of the element to return 563 * @return the element at the specified position in this fluent iterable 564 * @throws IndexOutOfBoundsException if {@code position} is negative or greater than or equal to 565 * the size of this fluent iterable 566 */ 567 @CheckReturnValue 568 public final E get(int position) { 569 return Iterables.get(iterable, position); 570 } 571 572 /** 573 * Function that transforms {@code Iterable<E>} into a fluent iterable. 574 */ 575 private static class FromIterableFunction<E> implements Function<Iterable<E>, FluentIterable<E>> { 576 @Override 577 public FluentIterable<E> apply(Iterable<E> fromObject) { 578 return FluentIterable.from(fromObject); 579 } 580 } 581}