diff options
Diffstat (limited to 'android/guava/src/com/google/common/collect/ImmutableListMultimap.java')
-rw-r--r-- | android/guava/src/com/google/common/collect/ImmutableListMultimap.java | 96 |
1 files changed, 87 insertions, 9 deletions
diff --git a/android/guava/src/com/google/common/collect/ImmutableListMultimap.java b/android/guava/src/com/google/common/collect/ImmutableListMultimap.java index fbc8ce2f5..deab19d8a 100644 --- a/android/guava/src/com/google/common/collect/ImmutableListMultimap.java +++ b/android/guava/src/com/google/common/collect/ImmutableListMultimap.java @@ -16,6 +16,8 @@ package com.google.common.collect; +import static java.util.Objects.requireNonNull; + import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.annotations.J2ktIncompatible; @@ -31,7 +33,11 @@ import java.util.Collection; import java.util.Comparator; import java.util.Map; import java.util.Map.Entry; +import java.util.function.Function; +import java.util.stream.Collector; +import java.util.stream.Stream; import javax.annotation.CheckForNull; +import org.checkerframework.checker.nullness.qual.Nullable; /** * A {@link ListMultimap} whose contents will never change, with many other important properties @@ -47,6 +53,78 @@ import javax.annotation.CheckForNull; @ElementTypesAreNonnullByDefault public class ImmutableListMultimap<K, V> extends ImmutableMultimap<K, V> implements ListMultimap<K, V> { + /** + * Returns a {@link Collector} that accumulates elements into an {@code ImmutableListMultimap} + * whose keys and values are the result of applying the provided mapping functions to the input + * elements. + * + * <p>For streams with defined encounter order (as defined in the Ordering section of the {@link + * java.util.stream} Javadoc), that order is preserved, but entries are <a + * href="ImmutableMultimap.html#iteration">grouped by key</a>. + * + * <p>Example: + * + * <pre>{@code + * static final Multimap<Character, String> FIRST_LETTER_MULTIMAP = + * Stream.of("banana", "apple", "carrot", "asparagus", "cherry") + * .collect(toImmutableListMultimap(str -> str.charAt(0), str -> str.substring(1))); + * + * // is equivalent to + * + * static final Multimap<Character, String> FIRST_LETTER_MULTIMAP = + * new ImmutableListMultimap.Builder<Character, String>() + * .put('b', "anana") + * .putAll('a', "pple", "sparagus") + * .putAll('c', "arrot", "herry") + * .build(); + * }</pre> + */ + @SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"}) + @IgnoreJRERequirement // Users will use this only if they're already using streams. + static <T extends @Nullable Object, K, V> + Collector<T, ?, ImmutableListMultimap<K, V>> toImmutableListMultimap( + Function<? super T, ? extends K> keyFunction, + Function<? super T, ? extends V> valueFunction) { + return CollectCollectors.toImmutableListMultimap(keyFunction, valueFunction); + } + + /** + * Returns a {@code Collector} accumulating entries into an {@code ImmutableListMultimap}. Each + * input element is mapped to a key and a stream of values, each of which are put into the + * resulting {@code Multimap}, in the encounter order of the stream and the encounter order of the + * streams of values. + * + * <p>Example: + * + * <pre>{@code + * static final ImmutableListMultimap<Character, Character> FIRST_LETTER_MULTIMAP = + * Stream.of("banana", "apple", "carrot", "asparagus", "cherry") + * .collect( + * flatteningToImmutableListMultimap( + * str -> str.charAt(0), + * str -> str.substring(1).chars().mapToObj(c -> (char) c)); + * + * // is equivalent to + * + * static final ImmutableListMultimap<Character, Character> FIRST_LETTER_MULTIMAP = + * ImmutableListMultimap.<Character, Character>builder() + * .putAll('b', Arrays.asList('a', 'n', 'a', 'n', 'a')) + * .putAll('a', Arrays.asList('p', 'p', 'l', 'e')) + * .putAll('c', Arrays.asList('a', 'r', 'r', 'o', 't')) + * .putAll('a', Arrays.asList('s', 'p', 'a', 'r', 'a', 'g', 'u', 's')) + * .putAll('c', Arrays.asList('h', 'e', 'r', 'r', 'y')) + * .build(); + * } + * }</pre> + */ + @SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"}) + @IgnoreJRERequirement // Users will use this only if they're already using streams. + static <T extends @Nullable Object, K, V> + Collector<T, ?, ImmutableListMultimap<K, V>> flatteningToImmutableListMultimap( + Function<? super T, ? extends K> keyFunction, + Function<? super T, ? extends Stream<? extends V>> valuesFunction) { + return CollectCollectors.flatteningToImmutableListMultimap(keyFunction, valuesFunction); + } /** * Returns the empty multimap. @@ -194,6 +272,13 @@ public class ImmutableListMultimap<K, V> extends ImmutableMultimap<K, V> return this; } + @CanIgnoreReturnValue + @Override + Builder<K, V> combine(ImmutableMultimap.Builder<K, V> other) { + super.combine(other); + return this; + } + /** * {@inheritDoc} * @@ -218,13 +303,6 @@ public class ImmutableListMultimap<K, V> extends ImmutableMultimap<K, V> return this; } - @CanIgnoreReturnValue - @Override - Builder<K, V> combine(ImmutableMultimap.Builder<K, V> other) { - super.combine(other); - return this; - } - /** Returns a newly-created immutable list multimap. */ @Override public ImmutableListMultimap<K, V> build() { @@ -397,7 +475,7 @@ public class ImmutableListMultimap<K, V> extends ImmutableMultimap<K, V> int tmpSize = 0; for (int i = 0; i < keyCount; i++) { - Object key = stream.readObject(); + Object key = requireNonNull(stream.readObject()); int valueCount = stream.readInt(); if (valueCount <= 0) { throw new InvalidObjectException("Invalid value count " + valueCount); @@ -405,7 +483,7 @@ public class ImmutableListMultimap<K, V> extends ImmutableMultimap<K, V> ImmutableList.Builder<Object> valuesBuilder = ImmutableList.builder(); for (int j = 0; j < valueCount; j++) { - valuesBuilder.add(stream.readObject()); + valuesBuilder.add(requireNonNull(stream.readObject())); } builder.put(key, valuesBuilder.build()); tmpSize += valueCount; |