aboutsummaryrefslogtreecommitdiff
path: root/android/guava/src/com/google/common/collect/Multimaps.java
diff options
context:
space:
mode:
Diffstat (limited to 'android/guava/src/com/google/common/collect/Multimaps.java')
-rw-r--r--android/guava/src/com/google/common/collect/Multimaps.java112
1 files changed, 104 insertions, 8 deletions
diff --git a/android/guava/src/com/google/common/collect/Multimaps.java b/android/guava/src/com/google/common/collect/Multimaps.java
index ea4148801..34d56b077 100644
--- a/android/guava/src/com/google/common/collect/Multimaps.java
+++ b/android/guava/src/com/google/common/collect/Multimaps.java
@@ -51,6 +51,8 @@ import java.util.NavigableSet;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.SortedSet;
+import java.util.stream.Collector;
+import java.util.stream.Stream;
import javax.annotation.CheckForNull;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -73,6 +75,100 @@ public final class Multimaps {
private Multimaps() {}
/**
+ * Returns a {@code Collector} accumulating entries into a {@code Multimap} generated from the
+ * specified supplier. The keys and values of the entries are the result of applying the provided
+ * mapping functions to the input elements, accumulated in the encounter order of the stream.
+ *
+ * <p>Example:
+ *
+ * <pre>{@code
+ * static final ListMultimap<Character, String> FIRST_LETTER_MULTIMAP =
+ * Stream.of("banana", "apple", "carrot", "asparagus", "cherry")
+ * .collect(
+ * toMultimap(
+ * str -> str.charAt(0),
+ * str -> str.substring(1),
+ * MultimapBuilder.treeKeys().arrayListValues()::build));
+ *
+ * // is equivalent to
+ *
+ * static final ListMultimap<Character, String> FIRST_LETTER_MULTIMAP;
+ *
+ * static {
+ * FIRST_LETTER_MULTIMAP = MultimapBuilder.treeKeys().arrayListValues().build();
+ * FIRST_LETTER_MULTIMAP.put('b', "anana");
+ * FIRST_LETTER_MULTIMAP.put('a', "pple");
+ * FIRST_LETTER_MULTIMAP.put('a', "sparagus");
+ * FIRST_LETTER_MULTIMAP.put('c', "arrot");
+ * FIRST_LETTER_MULTIMAP.put('c', "herry");
+ * }
+ * }</pre>
+ *
+ * <p>To collect to an {@link ImmutableMultimap}, use either {@link
+ * ImmutableSetMultimap#toImmutableSetMultimap} or {@link
+ * ImmutableListMultimap#toImmutableListMultimap}.
+ */
+ @SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"})
+ @IgnoreJRERequirement // Users will use this only if they're already using streams.
+ static <
+ T extends @Nullable Object,
+ K extends @Nullable Object,
+ V extends @Nullable Object,
+ M extends Multimap<K, V>>
+ Collector<T, ?, M> toMultimap(
+ java.util.function.Function<? super T, ? extends K> keyFunction,
+ java.util.function.Function<? super T, ? extends V> valueFunction,
+ java.util.function.Supplier<M> multimapSupplier) {
+ return CollectCollectors.<T, K, V, M>toMultimap(keyFunction, valueFunction, multimapSupplier);
+ }
+
+ /**
+ * Returns a {@code Collector} accumulating entries into a {@code Multimap} generated from the
+ * specified supplier. 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 ListMultimap<Character, Character> FIRST_LETTER_MULTIMAP =
+ * Stream.of("banana", "apple", "carrot", "asparagus", "cherry")
+ * .collect(
+ * flatteningToMultimap(
+ * str -> str.charAt(0),
+ * str -> str.substring(1).chars().mapToObj(c -> (char) c),
+ * MultimapBuilder.linkedHashKeys().arrayListValues()::build));
+ *
+ * // is equivalent to
+ *
+ * static final ListMultimap<Character, Character> FIRST_LETTER_MULTIMAP;
+ *
+ * static {
+ * FIRST_LETTER_MULTIMAP = MultimapBuilder.linkedHashKeys().arrayListValues().build();
+ * FIRST_LETTER_MULTIMAP.putAll('b', Arrays.asList('a', 'n', 'a', 'n', 'a'));
+ * FIRST_LETTER_MULTIMAP.putAll('a', Arrays.asList('p', 'p', 'l', 'e'));
+ * FIRST_LETTER_MULTIMAP.putAll('c', Arrays.asList('a', 'r', 'r', 'o', 't'));
+ * FIRST_LETTER_MULTIMAP.putAll('a', Arrays.asList('s', 'p', 'a', 'r', 'a', 'g', 'u', 's'));
+ * FIRST_LETTER_MULTIMAP.putAll('c', Arrays.asList('h', 'e', 'r', 'r', 'y'));
+ * }
+ * }</pre>
+ */
+ @SuppressWarnings({"AndroidJdkLibsChecker", "Java7ApiChecker"})
+ @IgnoreJRERequirement // Users will use this only if they're already using streams.
+ static <
+ T extends @Nullable Object,
+ K extends @Nullable Object,
+ V extends @Nullable Object,
+ M extends Multimap<K, V>>
+ Collector<T, ?, M> flatteningToMultimap(
+ java.util.function.Function<? super T, ? extends K> keyFunction,
+ java.util.function.Function<? super T, ? extends Stream<? extends V>> valueFunction,
+ java.util.function.Supplier<M> multimapSupplier) {
+ return CollectCollectors.<T, K, V, M>flatteningToMultimap(
+ keyFunction, valueFunction, multimapSupplier);
+ }
+
+ /**
* Creates a new {@code Multimap} backed by {@code map}, whose internal value collections are
* generated by {@code factory}.
*
@@ -187,8 +283,8 @@ public final class Multimaps {
@SuppressWarnings("unchecked") // reading data stored by writeObject
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
- factory = (Supplier<? extends Collection<V>>) stream.readObject();
- Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
+ factory = (Supplier<? extends Collection<V>>) requireNonNull(stream.readObject());
+ Map<K, Collection<V>> map = (Map<K, Collection<V>>) requireNonNull(stream.readObject());
setMap(map);
}
@@ -273,8 +369,8 @@ public final class Multimaps {
@SuppressWarnings("unchecked") // reading data stored by writeObject
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
- factory = (Supplier<? extends List<V>>) stream.readObject();
- Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
+ factory = (Supplier<? extends List<V>>) requireNonNull(stream.readObject());
+ Map<K, Collection<V>> map = (Map<K, Collection<V>>) requireNonNull(stream.readObject());
setMap(map);
}
@@ -381,8 +477,8 @@ public final class Multimaps {
@SuppressWarnings("unchecked") // reading data stored by writeObject
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
- factory = (Supplier<? extends Set<V>>) stream.readObject();
- Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
+ factory = (Supplier<? extends Set<V>>) requireNonNull(stream.readObject());
+ Map<K, Collection<V>> map = (Map<K, Collection<V>>) requireNonNull(stream.readObject());
setMap(map);
}
@@ -475,9 +571,9 @@ public final class Multimaps {
@SuppressWarnings("unchecked") // reading data stored by writeObject
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
- factory = (Supplier<? extends SortedSet<V>>) stream.readObject();
+ factory = (Supplier<? extends SortedSet<V>>) requireNonNull(stream.readObject());
valueComparator = factory.get().comparator();
- Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
+ Map<K, Collection<V>> map = (Map<K, Collection<V>>) requireNonNull(stream.readObject());
setMap(map);
}