guava/src/com/google/common/collect/FluentIterable.java
public final <K> ImmutableMap<K, E> uniqueIndex(Function<? super E, K> keyFunction) {
    return Maps.uniqueIndex(getDelegate(), keyFunction);
  }
public final <K> ImmutableMap<K, E> uniqueIndex(Function<? super E, K> keyFunction) {
    return Maps.uniqueIndex(getDelegate(), keyFunction);
  }
Returns a map with the contents of this {@code FluentIterable} as its {@code values}, indexed
by keys derived from those values. In other words, each input value produces an entry in the
map whose key is the result of applying {@code keyFunction} to that value. These entries appear
in the same order as they appeared in this fluent iterable. Example usage:

<pre>{@code
Color red = new Color("red", 255, 0, 0);
...
FluentIterable<Color> allColors = FluentIterable.from(ImmutableSet.of(red, green, blue));

Map<String, Color> colorForName = allColors.uniqueIndex(toStringFunction());
assertThat(colorForName).containsEntry("red", red);
}</pre>

<p>If your index may associate multiple values with each key, use {@link #index(Function)
index}.

<p><b>{@code Stream} equivalent:</b> {@code
stream.collect(ImmutableMap.toImmutableMap(keyFunction, v -> v))}.

@param keyFunction the function used to produce the key for each value
@return a map mapping the result of evaluating the function {@code keyFunction} on each value
in this fluent iterable to that value
@throws IllegalArgumentException if {@code keyFunction} produces the same key for more than one
value in this fluent iterable
@throws NullPointerException if any element of this iterable is {@code null}, or if {@code
keyFunction} produces {@code null} for any key
@since 14.0