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 * An expanded {@code Iterable} API, providing functionality similar to Java 8's powerful <a href= 041 * "https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#package.description" 042 * >streams library</a> in a slightly different way. 043 * 044 * <p>The following types of methods are provided: 045 * 046 * <ul> 047 * <li>chaining methods which return a new {@code FluentIterable} based in some way on the contents 048 * of the current one (for example {@link #transform}) 049 * <li>element extraction methods which facilitate the retrieval of certain elements (for example 050 * {@link #last}) 051 * <li>query methods which answer questions about the {@code FluentIterable}'s contents (for example 052 * {@link #anyMatch}) 053 * <li>conversion methods which copy the {@code FluentIterable}'s contents into a new collection or 054 * array (for example {@link #toList}) 055 * </ul> 056 * 057 * <p>Several lesser-used features are currently available only as static methods on the {@link 058 * Iterables} class. 059 * 060 * <a name="streams"></a> 061 * <h3>Comparison to streams</h3> 062 * 063 * <p>Starting with Java 8, the core Java class libraries provide a new "Streams" library (in {@code 064 * java.util.stream}), which is similar to {@code FluentIterable} but generally more powerful. Key 065 * differences include:</b> 066 * 067 * <ul> 068 * <li>A stream is <i>single-use</i>; it becomes invalid as soon as any "terminal operation" such as 069 * {@code findFirst()} or {@code iterator()} is invoked. (Even though {@code Stream} contains 070 * all the right method <i>signatures</i> to implement {@link Iterable}, it does not actually 071 * do so, to avoid implying repeat-iterability.) {@code FluentIterable}, on the other hand, is 072 * multiple-use, and does implement {@link Iterable}. 073 * <li>Streams offer many features not found here, including {@code min/max}, {@code 074 * distinct}, {@code reduce}, {@code sorted}, the very powerful {@code collect}, and built-in 075 * support for parallelizing stream operations. 076 * <li>{@code FluentIterable} contains several features not available on {@code Stream}, which are 077 * noted in the method descriptions below. 078 * <li>Streams include primitive-specialized variants such as {@code IntStream}, the use of which is 079 * strongly recommended. 080 * <li>Streams are standard Java, not requiring a third-party dependency (but do render your code 081 * incompatible with Java 7 and earlier). 082 * </ul> 083 * 084 * <h3>Example</h3> 085 * 086 * <p>Here is an example that accepts a list from a database call, filters it based on a predicate, 087 * transforms it by invoking {@code toString()} on each element, and returns the first 10 elements 088 * as a {@code List}: <pre> {@code 089 * 090 * List<String> results = 091 * FluentIterable.from(database.getClientList()) 092 * .filter(activeInLastMonthPredicate) 093 * .transform(Functions.toStringFunction()) 094 * .limit(10) 095 * .toList();}</pre> 096 * 097 * The approximate stream equivalent is: <pre> {@code 098 * 099 * List<String> results = 100 * database.getClientList() 101 * .stream() 102 * .filter(activeInLastMonthPredicate) 103 * .map(Functions.toStringFunction()) 104 * .limit(10) 105 * .collect(Collectors.toList());}</pre> 106 * 107 * @author Marcin Mikosik 108 * @since 12.0 109 */ 110@GwtCompatible(emulated = true) 111public abstract class FluentIterable<E> implements Iterable<E> { 112 // We store 'iterable' and use it instead of 'this' to allow Iterables to perform instanceof 113 // checks on the _original_ iterable when FluentIterable.from is used. 114 private final Iterable<E> iterable; 115 116 /** Constructor for use by subclasses. */ 117 protected FluentIterable() { 118 this.iterable = this; 119 } 120 121 FluentIterable(Iterable<E> iterable) { 122 this.iterable = checkNotNull(iterable); 123 } 124 125 /** 126 * Returns a fluent iterable that wraps {@code iterable}, or {@code iterable} itself if it 127 * is already a {@code FluentIterable}. 128 * 129 * <p><b>{@code Stream} equivalent:</b> {@code iterable.stream()} if {@code iterable} is a 130 * {@link Collection}; {@code StreamSupport.stream(iterable.spliterator(), false)} otherwise. 131 */ 132 @CheckReturnValue 133 public static <E> FluentIterable<E> from(final Iterable<E> iterable) { 134 return (iterable instanceof FluentIterable) 135 ? (FluentIterable<E>) iterable 136 : new FluentIterable<E>(iterable) { 137 @Override 138 public Iterator<E> iterator() { 139 return iterable.iterator(); 140 } 141 }; 142 } 143 144 /** 145 * Construct a fluent iterable from another fluent iterable. This is obviously never necessary, 146 * but is intended to help call out cases where one migration from {@code Iterable} to 147 * {@code FluentIterable} has obviated the need to explicitly convert to a {@code FluentIterable}. 148 * 149 * @deprecated instances of {@code FluentIterable} don't need to be converted to 150 * {@code FluentIterable} 151 */ 152 @Deprecated 153 @CheckReturnValue 154 public static <E> FluentIterable<E> from(FluentIterable<E> iterable) { 155 return checkNotNull(iterable); 156 } 157 158 /** 159 * Returns a fluent iterable containing {@code elements} in the specified order. 160 * 161 * <p><b>{@code Stream} equivalent:</b> {@code Stream.of(elements)} or {@code 162 * Arrays.stream(elements)}. 163 * 164 * @since 18.0 165 */ 166 @Beta 167 @CheckReturnValue 168 public static <E> FluentIterable<E> of(E[] elements) { 169 return from(Lists.newArrayList(elements)); 170 } 171 172 /** 173 * Returns a string representation of this fluent iterable, with the format 174 * {@code [e1, e2, ..., en]}. 175 * 176 * <p><b>{@code Stream} equivalent:</b> {@code stream.collect(Collectors.joining(", ", "[", "]"))} 177 * or (less efficiently) {@code collect(Collectors.toList()).toString()}. 178 */ 179 @Override 180 @CheckReturnValue 181 public String toString() { 182 return Iterables.toString(iterable); 183 } 184 185 /** 186 * Returns the number of elements in this fluent iterable. 187 * 188 * <p><b>{@code Stream} equivalent:</b> {@code stream.count()}. 189 */ 190 @CheckReturnValue 191 public final int size() { 192 return Iterables.size(iterable); 193 } 194 195 /** 196 * Returns {@code true} if this fluent iterable contains any object for which 197 * {@code equals(target)} is true. 198 * 199 * <p><b>{@code Stream} equivalent:</b> {@code stream.anyMatch(Predicate.isEqual(target))}. 200 */ 201 @CheckReturnValue 202 public final boolean contains(@Nullable Object target) { 203 return Iterables.contains(iterable, target); 204 } 205 206 /** 207 * Returns a fluent iterable whose {@code Iterator} cycles indefinitely over the elements of 208 * this fluent iterable. 209 * 210 * <p>That iterator supports {@code remove()} if {@code iterable.iterator()} does. After 211 * {@code remove()} is called, subsequent cycles omit the removed element, which is no longer in 212 * this fluent iterable. The iterator's {@code hasNext()} method returns {@code true} until 213 * this fluent iterable is empty. 214 * 215 * <p><b>Warning:</b> Typical uses of the resulting iterator may produce an infinite loop. You 216 * should use an explicit {@code break} or be certain that you will eventually remove all the 217 * elements. 218 * 219 * <p><b>{@code Stream} equivalent:</b> if the source iterable has only a single element {@code 220 * element}, use {@code Stream.generate(() -> element)}. Otherwise, if the source iterable has 221 * a {@code stream} method (for example, if it is a {@link Collection}), use 222 * {@code Stream.generate(iterable::stream).flatMap(s -> s)}. 223 */ 224 @CheckReturnValue 225 public final FluentIterable<E> cycle() { 226 return from(Iterables.cycle(iterable)); 227 } 228 229 /** 230 * Returns a fluent iterable whose iterators traverse first the elements of this fluent iterable, 231 * followed by those of {@code other}. The iterators are not polled until necessary. 232 * 233 * <p>The returned iterable's {@code Iterator} supports {@code remove()} when the corresponding 234 * {@code Iterator} supports it. 235 * 236 * <p><b>{@code Stream} equivalent:</b> {@code Stream.concat(thisStream, otherStream)}. 237 * 238 * @since 18.0 239 */ 240 @Beta 241 @CheckReturnValue 242 public final FluentIterable<E> append(Iterable<? extends E> other) { 243 return from(Iterables.concat(iterable, other)); 244 } 245 246 /** 247 * Returns a fluent iterable whose iterators traverse first the elements of this fluent iterable, 248 * followed by {@code elements}. 249 * 250 * <p><b>{@code Stream} equivalent:</b> {@code Stream.concat(thisStream, Stream.of(elements))}. 251 * 252 * @since 18.0 253 */ 254 @Beta 255 @CheckReturnValue 256 public final FluentIterable<E> append(E... elements) { 257 return from(Iterables.concat(iterable, Arrays.asList(elements))); 258 } 259 260 /** 261 * Returns the elements from this fluent iterable that satisfy a predicate. The 262 * resulting fluent iterable's iterator does not support {@code remove()}. 263 * 264 * <p><b>{@code Stream} equivalent:</b> {@code stream.filter(predicate)} (same). 265 */ 266 @CheckReturnValue 267 public final FluentIterable<E> filter(Predicate<? super E> predicate) { 268 return from(Iterables.filter(iterable, predicate)); 269 } 270 271 /** 272 * Returns the elements from this fluent iterable that are instances of class {@code type}. 273 * 274 * @param type the type of elements desired 275 * 276 * <p><b>{@code Stream} equivalent:</b> <pre> {@code 277 * 278 * @SuppressWarnings("unchecked") // safe by runtime check 279 * Stream<T> result = (Stream) stream.filter(type::isInstance);}</pre> 280 * 281 * ... or if {@code type} is a class literal {@code MyType.class}, <pre> {@code 282 * 283 * @SuppressWarnings("unchecked") // safe by runtime check 284 * Stream<MyType> result = (Stream) stream.filter(e -> e instanceof MyType);}</pre> 285 */ 286 @GwtIncompatible("Class.isInstance") 287 @CheckReturnValue 288 public final <T> FluentIterable<T> filter(Class<T> type) { 289 return from(Iterables.filter(iterable, type)); 290 } 291 292 /** 293 * Returns {@code true} if any element in this fluent iterable satisfies the predicate. 294 * 295 * <p><b>{@code Stream} equivalent:</b> {@code stream.anyMatch(predicate)} (same). 296 */ 297 @CheckReturnValue 298 public final boolean anyMatch(Predicate<? super E> predicate) { 299 return Iterables.any(iterable, predicate); 300 } 301 302 /** 303 * Returns {@code true} if every element in this fluent iterable satisfies the predicate. 304 * If this fluent iterable is empty, {@code true} is returned. 305 * 306 * <p><b>{@code Stream} equivalent:</b> {@code stream.allMatch(predicate)} (same). 307 */ 308 @CheckReturnValue 309 public final boolean allMatch(Predicate<? super E> predicate) { 310 return Iterables.all(iterable, predicate); 311 } 312 313 /** 314 * Returns an {@link Optional} containing the first element in this fluent iterable that 315 * satisfies the given predicate, if such an element exists. 316 * 317 * <p><b>Warning:</b> avoid using a {@code predicate} that matches {@code null}. If {@code null} 318 * is matched in this fluent iterable, a {@link NullPointerException} will be thrown. 319 * 320 * <p><b>{@code Stream} equivalent:</b> {@code stream.filter(predicate).findFirst()}. 321 */ 322 @CheckReturnValue 323 public final Optional<E> firstMatch(Predicate<? super E> predicate) { 324 return Iterables.tryFind(iterable, predicate); 325 } 326 327 /** 328 * Returns a fluent iterable that applies {@code function} to each element of this 329 * fluent iterable. 330 * 331 * <p>The returned fluent iterable's iterator supports {@code remove()} if this iterable's 332 * iterator does. After a successful {@code remove()} call, this fluent iterable no longer 333 * contains the corresponding element. 334 * 335 * <p><b>{@code Stream} equivalent:</b> {@code stream.map(function)}. 336 */ 337 @CheckReturnValue 338 public final <T> FluentIterable<T> transform(Function<? super E, T> function) { 339 return from(Iterables.transform(iterable, function)); 340 } 341 342 /** 343 * Applies {@code function} to each element of this fluent iterable and returns 344 * a fluent iterable with the concatenated combination of results. {@code function} 345 * returns an Iterable of results. 346 * 347 * <p>The returned fluent iterable's iterator supports {@code remove()} if this 348 * function-returned iterables' iterator does. After a successful {@code remove()} call, 349 * the returned fluent iterable no longer contains the corresponding element. 350 * 351 * <p><b>{@code Stream} equivalent:</b> {@code stream.flatMap(function)} (using a function that 352 * produces streams, not iterables). 353 * 354 * @since 13.0 (required {@code Function<E, Iterable<T>>} until 14.0) 355 */ 356 @CheckReturnValue 357 public <T> FluentIterable<T> transformAndConcat( 358 Function<? super E, ? extends Iterable<? extends T>> function) { 359 return from(Iterables.concat(transform(function))); 360 } 361 362 /** 363 * Returns an {@link Optional} containing the first element in this fluent iterable. 364 * If the iterable is empty, {@code Optional.absent()} is returned. 365 * 366 * <p><b>{@code Stream} equivalent:</b> if the goal is to obtain any element, {@code 367 * stream.findAny()}; if it must specifically be the <i>first</i> element, {@code 368 * stream.findFirst()}. 369 * 370 * @throws NullPointerException if the first element is null; if this is a possibility, use 371 * {@code iterator().next()} or {@link Iterables#getFirst} instead. 372 */ 373 @CheckReturnValue 374 public final Optional<E> first() { 375 Iterator<E> iterator = iterable.iterator(); 376 return iterator.hasNext() ? Optional.of(iterator.next()) : Optional.<E>absent(); 377 } 378 379 /** 380 * Returns an {@link Optional} containing the last element in this fluent iterable. 381 * If the iterable is empty, {@code Optional.absent()} is returned. 382 * 383 * <p><b>{@code Stream} equivalent:</b> {@code stream.reduce((a, b) -> b)}. 384 * 385 * @throws NullPointerException if the last element is null; if this is a possibility, use 386 * {@link Iterables#getLast} instead. 387 */ 388 @CheckReturnValue 389 public final Optional<E> last() { 390 // Iterables#getLast was inlined here so we don't have to throw/catch a NSEE 391 392 // TODO(kevinb): Support a concurrently modified collection? 393 if (iterable instanceof List) { 394 List<E> list = (List<E>) iterable; 395 if (list.isEmpty()) { 396 return Optional.absent(); 397 } 398 return Optional.of(list.get(list.size() - 1)); 399 } 400 Iterator<E> iterator = iterable.iterator(); 401 if (!iterator.hasNext()) { 402 return Optional.absent(); 403 } 404 405 /* 406 * TODO(kevinb): consider whether this "optimization" is worthwhile. Users 407 * with SortedSets tend to know they are SortedSets and probably would not 408 * call this method. 409 */ 410 if (iterable instanceof SortedSet) { 411 SortedSet<E> sortedSet = (SortedSet<E>) iterable; 412 return Optional.of(sortedSet.last()); 413 } 414 415 while (true) { 416 E current = iterator.next(); 417 if (!iterator.hasNext()) { 418 return Optional.of(current); 419 } 420 } 421 } 422 423 /** 424 * Returns a view of this fluent iterable that skips its first {@code numberToSkip} 425 * elements. If this fluent iterable contains fewer than {@code numberToSkip} elements, 426 * the returned fluent iterable skips all of its elements. 427 * 428 * <p>Modifications to this fluent iterable before a call to {@code iterator()} are 429 * reflected in the returned fluent iterable. That is, the its iterator skips the first 430 * {@code numberToSkip} elements that exist when the iterator is created, not when {@code skip()} 431 * is called. 432 * 433 * <p>The returned fluent iterable's iterator supports {@code remove()} if the 434 * {@code Iterator} of this fluent iterable supports it. Note that it is <i>not</i> 435 * possible to delete the last skipped element by immediately calling {@code remove()} on the 436 * returned fluent iterable's iterator, as the {@code Iterator} contract states that a call 437 * to {@code * remove()} before a call to {@code next()} will throw an 438 * {@link IllegalStateException}. 439 * 440 * <p><b>{@code Stream} equivalent:</b> {@code stream.skip(numberToSkip)} (same). 441 */ 442 @CheckReturnValue 443 public final FluentIterable<E> skip(int numberToSkip) { 444 return from(Iterables.skip(iterable, numberToSkip)); 445 } 446 447 /** 448 * Creates a fluent iterable with the first {@code size} elements of this 449 * fluent iterable. If this fluent iterable does not contain that many elements, 450 * the returned fluent iterable will have the same behavior as this fluent iterable. 451 * The returned fluent iterable's iterator supports {@code remove()} if this 452 * fluent iterable's iterator does. 453 * 454 * <p><b>{@code Stream} equivalent:</b> {@code stream.limit(maxSize)} (same). 455 * 456 * @param maxSize the maximum number of elements in the returned fluent iterable 457 * @throws IllegalArgumentException if {@code size} is negative 458 */ 459 @CheckReturnValue 460 public final FluentIterable<E> limit(int maxSize) { 461 return from(Iterables.limit(iterable, maxSize)); 462 } 463 464 /** 465 * Determines whether this fluent iterable is empty. 466 * 467 * <p><b>{@code Stream} equivalent:</b> {@code !stream.findAny().isPresent()}. 468 */ 469 @CheckReturnValue 470 public final boolean isEmpty() { 471 return !iterable.iterator().hasNext(); 472 } 473 474 /** 475 * Returns an {@code ImmutableList} containing all of the elements from this fluent iterable in 476 * proper sequence. 477 * 478 * <p><b>{@code Stream} equivalent:</b> {@code ImmutableList.copyOf(stream.iterator())}. 479 * 480 * @since 14.0 (since 12.0 as {@code toImmutableList()}). 481 */ 482 @CheckReturnValue 483 public final ImmutableList<E> toList() { 484 return ImmutableList.copyOf(iterable); 485 } 486 487 /** 488 * Returns an {@code ImmutableList} containing all of the elements from this {@code 489 * FluentIterable} in the order specified by {@code comparator}. To produce an {@code 490 * ImmutableList} sorted by its natural ordering, use {@code toSortedList(Ordering.natural())}. 491 * 492 * <p><b>{@code Stream} equivalent:</b> 493 * {@code ImmutableList.copyOf(stream.sorted(comparator).iterator())}. 494 * 495 * @param comparator the function by which to sort list elements 496 * @throws NullPointerException if any element is null 497 * @since 14.0 (since 13.0 as {@code toSortedImmutableList()}). 498 */ 499 @CheckReturnValue 500 public final ImmutableList<E> toSortedList(Comparator<? super E> comparator) { 501 return Ordering.from(comparator).immutableSortedCopy(iterable); 502 } 503 504 /** 505 * Returns an {@code ImmutableSet} containing all of the elements from this fluent iterable with 506 * duplicates removed. 507 * 508 * <p><b>{@code Stream} equivalent:</b> {@code ImmutableSet.copyOf(stream.iterator())}. 509 * 510 * @since 14.0 (since 12.0 as {@code toImmutableSet()}). 511 */ 512 @CheckReturnValue 513 public final ImmutableSet<E> toSet() { 514 return ImmutableSet.copyOf(iterable); 515 } 516 517 /** 518 * Returns an {@code ImmutableSortedSet} containing all of the elements from this {@code 519 * FluentIterable} in the order specified by {@code comparator}, with duplicates (determined by 520 * {@code comparator.compare(x, y) == 0}) removed. To produce an {@code ImmutableSortedSet} sorted 521 * by its natural ordering, use {@code toSortedSet(Ordering.natural())}. 522 * 523 * <p><b>{@code Stream} equivalent:</b> 524 * {@code ImmutableSortedSet.copyOf(comparator, stream.iterator())}. 525 * 526 * @param comparator the function by which to sort set elements 527 * @throws NullPointerException if any element is null 528 * @since 14.0 (since 12.0 as {@code toImmutableSortedSet()}). 529 */ 530 @CheckReturnValue 531 public final ImmutableSortedSet<E> toSortedSet(Comparator<? super E> comparator) { 532 return ImmutableSortedSet.copyOf(comparator, iterable); 533 } 534 535 /** 536 * Returns an {@code ImmutableMultiset} containing all of the elements from this fluent iterable. 537 * 538 * <p><b>{@code Stream} equivalent:</b> {@code ImmutableMultiset.copyOf(stream.iterator())}. 539 * 540 * @since 19.0 541 */ 542 @CheckReturnValue 543 public final ImmutableMultiset<E> toMultiset() { 544 return ImmutableMultiset.copyOf(iterable); 545 } 546 547 /** 548 * Returns an immutable map whose keys are the distinct elements of this {@code FluentIterable} 549 * and whose value for each key was computed by {@code valueFunction}. The map's iteration order 550 * is the order of the first appearance of each key in this iterable. 551 * 552 * <p>When there are multiple instances of a key in this iterable, it is unspecified whether 553 * {@code valueFunction} will be applied to more than one instance of that key and, if it is, 554 * which result will be mapped to that key in the returned map. 555 * 556 * <p><b>{@code Stream} equivalent:</b> {@code 557 * ImmutableMap.copyOf(stream.collect(Collectors.toMap(k -> k, valueFunction)))} (but note that 558 * this may not preserve the order of entries). 559 * 560 * @throws NullPointerException if any element of this iterable is {@code null}, or if {@code 561 * valueFunction} produces {@code null} for any key 562 * @since 14.0 563 */ 564 @CheckReturnValue 565 public final <V> ImmutableMap<E, V> toMap(Function<? super E, V> valueFunction) { 566 return Maps.toMap(iterable, valueFunction); 567 } 568 569 /** 570 * Creates an index {@code ImmutableListMultimap} that contains the results of applying a 571 * specified function to each item in this {@code FluentIterable} of values. Each element of this 572 * iterable will be stored as a value in the resulting multimap, yielding a multimap with the same 573 * size as this iterable. The key used to store that value in the multimap will be the result of 574 * calling the function on that value. The resulting multimap is created as an immutable snapshot. 575 * In the returned multimap, keys appear in the order they are first encountered, and the values 576 * corresponding to each key appear in the same order as they are encountered. 577 * 578 * @param keyFunction the function used to produce the key for each value 579 * @throws NullPointerException if any of the following cases is true: 580 * <ul> 581 * <li>{@code keyFunction} is null 582 * <li>An element in this fluent iterable is null 583 * <li>{@code keyFunction} returns {@code null} for any element of this iterable 584 * </ul> 585 * 586 * <p><b>{@code Stream} equivalent:</b> {@code stream.collect(Collectors.groupingBy(keyFunction))} 587 * behaves similarly, but returns a mutable {@code Map<K, List<E>>} instead, and may not preserve 588 * the order of entries). 589 * 590 * @since 14.0 591 */ 592 @CheckReturnValue 593 public final <K> ImmutableListMultimap<K, E> index(Function<? super E, K> keyFunction) { 594 return Multimaps.index(iterable, keyFunction); 595 } 596 597 /** 598 * Returns a map with the contents of this {@code FluentIterable} as its {@code values}, indexed 599 * by keys derived from those values. In other words, each input value produces an entry in the 600 * map whose key is the result of applying {@code keyFunction} to that value. These entries appear 601 * in the same order as they appeared in this fluent iterable. Example usage: 602 * <pre> {@code 603 * 604 * Color red = new Color("red", 255, 0, 0); 605 * ... 606 * FluentIterable<Color> allColors = FluentIterable.from(ImmutableSet.of(red, green, blue)); 607 * 608 * Map<String, Color> colorForName = allColors.uniqueIndex(toStringFunction()); 609 * assertThat(colorForName).containsEntry("red", red);}</pre> 610 * 611 * <p>If your index may associate multiple values with each key, use {@link #index(Function) 612 * index}. 613 * 614 * <p><b>{@code Stream} equivalent:</b> {@code 615 * ImmutableMap.copyOf(stream.collect(Collectors.toMap(keyFunction, v -> v)))} (but note that this 616 * may not preserve the order of entries). 617 * 618 * @param keyFunction the function used to produce the key for each value 619 * @return a map mapping the result of evaluating the function {@code 620 * keyFunction} on each value in this fluent iterable to that value 621 * @throws IllegalArgumentException if {@code keyFunction} produces the same 622 * key for more than one value in this fluent iterable 623 * @throws NullPointerException if any elements of this fluent iterable is null, or 624 * if {@code keyFunction} produces {@code null} for any value 625 * @since 14.0 626 */ 627 @CheckReturnValue 628 public final <K> ImmutableMap<K, E> uniqueIndex(Function<? super E, K> keyFunction) { 629 return Maps.uniqueIndex(iterable, keyFunction); 630 } 631 632 /** 633 * Returns an array containing all of the elements from this fluent iterable in iteration order. 634 * 635 * <p><b>{@code Stream} equivalent:</b> if an object array is acceptable, use 636 * {@code stream.toArray()}; if {@code type} is a class literal such as {@code MyType.class}, use 637 * {@code stream.toArray(MyType[]::new)}. Otherwise use {@code stream.toArray( 638 * len -> (E[]) Array.newInstance(type, len))}. 639 * 640 * @param type the type of the elements 641 * @return a newly-allocated array into which all the elements of this fluent iterable have 642 * been copied 643 */ 644 @GwtIncompatible("Array.newArray(Class, int)") 645 @CheckReturnValue 646 public final E[] toArray(Class<E> type) { 647 return Iterables.toArray(iterable, type); 648 } 649 650 /** 651 * Copies all the elements from this fluent iterable to {@code collection}. This is equivalent to 652 * calling {@code Iterables.addAll(collection, this)}. 653 * 654 * <p><b>{@code Stream} equivalent:</b> {@code stream.forEachOrdered(collection::add)} or 655 * {@code stream.forEach(collection::add)}. 656 * 657 * @param collection the collection to copy elements to 658 * @return {@code collection}, for convenience 659 * @since 14.0 660 */ 661 public final <C extends Collection<? super E>> C copyInto(C collection) { 662 checkNotNull(collection); 663 if (iterable instanceof Collection) { 664 collection.addAll(Collections2.cast(iterable)); 665 } else { 666 for (E item : iterable) { 667 collection.add(item); 668 } 669 } 670 return collection; 671 } 672 673 /** 674 * Returns a {@link String} containing all of the elements of this fluent iterable joined with 675 * {@code joiner}. 676 * 677 * <p><b>{@code Stream} equivalent:</b> {@code joiner.join(stream.iterator())}, or, if you are not 678 * using any optional {@code Joiner} features, 679 * {@code stream.collect(Collectors.joining(delimiter)}. 680 * 681 * @since 18.0 682 */ 683 @Beta 684 @CheckReturnValue 685 public final String join(Joiner joiner) { 686 return joiner.join(this); 687 } 688 689 /** 690 * Returns the element at the specified position in this fluent iterable. 691 * 692 * <p><b>{@code Stream} equivalent:</b> {@code stream.skip(position).findFirst().get()} (but note 693 * that this throws different exception types, and throws an exception if {@code null} would be 694 * returned). 695 * 696 * @param position position of the element to return 697 * @return the element at the specified position in this fluent iterable 698 * @throws IndexOutOfBoundsException if {@code position} is negative or greater than or equal to 699 * the size of this fluent iterable 700 */ 701 // TODO(kevinb): add @Nullable? 702 @CheckReturnValue 703 public final E get(int position) { 704 return Iterables.get(iterable, position); 705 } 706 707 /** 708 * Function that transforms {@code Iterable<E>} into a fluent iterable. 709 */ 710 private static class FromIterableFunction<E> implements Function<Iterable<E>, FluentIterable<E>> { 711 @Override 712 public FluentIterable<E> apply(Iterable<E> fromObject) { 713 return FluentIterable.from(fromObject); 714 } 715 } 716}