1063 lines
40 KiB
Java
1063 lines
40 KiB
Java
/*
|
|
* Copyright (C) 2007 The Guava Authors
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.google.common.collect;
|
|
|
|
import static com.google.common.base.Preconditions.checkArgument;
|
|
import static com.google.common.collect.Maps.immutableEntry;
|
|
import static com.google.common.collect.Sets.newHashSet;
|
|
import static com.google.common.collect.testing.Helpers.mapEntry;
|
|
import static com.google.common.collect.testing.Helpers.nefariousMapEntry;
|
|
import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
|
|
import static com.google.common.truth.Truth.assertThat;
|
|
import static java.util.Arrays.asList;
|
|
|
|
import com.google.common.annotations.GwtCompatible;
|
|
import com.google.common.annotations.GwtIncompatible;
|
|
import com.google.common.base.Equivalence;
|
|
import com.google.common.base.Function;
|
|
import com.google.common.base.Functions;
|
|
import com.google.common.base.Predicates;
|
|
import com.google.common.base.Supplier;
|
|
import com.google.common.collect.Maps.EntryTransformer;
|
|
import com.google.common.collect.testing.IteratorTester;
|
|
import com.google.common.collect.testing.google.UnmodifiableCollectionTests;
|
|
import com.google.common.testing.CollectorTester;
|
|
import com.google.common.testing.EqualsTester;
|
|
import com.google.common.testing.NullPointerTester;
|
|
import com.google.common.testing.SerializableTester;
|
|
import java.io.Serializable;
|
|
import java.util.Arrays;
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.Comparator;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.Iterator;
|
|
import java.util.LinkedList;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Map.Entry;
|
|
import java.util.NavigableSet;
|
|
import java.util.Queue;
|
|
import java.util.RandomAccess;
|
|
import java.util.Set;
|
|
import java.util.SortedMap;
|
|
import java.util.SortedSet;
|
|
import java.util.TreeSet;
|
|
import java.util.function.BiPredicate;
|
|
import java.util.stream.Collector;
|
|
import java.util.stream.Stream;
|
|
import junit.framework.TestCase;
|
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
|
|
|
/**
|
|
* Unit test for {@code Multimaps}.
|
|
*
|
|
* @author Jared Levy
|
|
*/
|
|
@GwtCompatible(emulated = true)
|
|
public class MultimapsTest extends TestCase {
|
|
|
|
private static final Comparator<Integer> INT_COMPARATOR =
|
|
Ordering.<Integer>natural().reverse().nullsFirst();
|
|
|
|
public void testMultimapCollectorGenerics() {
|
|
ListMultimap<Integer, String> unused =
|
|
Stream.of("foo", "bar", "quux")
|
|
.collect(
|
|
Multimaps.toMultimap(
|
|
String::length, s -> s, MultimapBuilder.treeKeys().arrayListValues()::build));
|
|
}
|
|
|
|
public void testToMultimap() {
|
|
Collector<Entry<String, Integer>, ?, TreeMultimap<String, Integer>> collector =
|
|
Multimaps.toMultimap(Entry::getKey, Entry::getValue, TreeMultimap::create);
|
|
BiPredicate<Multimap<?, ?>, Multimap<?, ?>> equivalence =
|
|
Equivalence.equals()
|
|
.onResultOf((Multimap<?, ?> mm) -> ImmutableList.copyOf(mm.asMap().entrySet()))
|
|
.and(Equivalence.equals());
|
|
TreeMultimap<String, Integer> empty = TreeMultimap.create();
|
|
TreeMultimap<String, Integer> filled = TreeMultimap.create();
|
|
filled.put("a", 1);
|
|
filled.put("a", 2);
|
|
filled.put("b", 2);
|
|
filled.put("c", 3);
|
|
CollectorTester.of(collector, equivalence)
|
|
.expectCollects(empty)
|
|
.expectCollects(
|
|
filled, mapEntry("a", 1), mapEntry("a", 2), mapEntry("b", 2), mapEntry("c", 3));
|
|
}
|
|
|
|
public void testFlatteningToMultimap() {
|
|
Collector<String, ?, ListMultimap<Character, Character>> collector =
|
|
Multimaps.flatteningToMultimap(
|
|
str -> str.charAt(0),
|
|
str -> str.substring(1).chars().mapToObj(c -> (char) c),
|
|
MultimapBuilder.linkedHashKeys().arrayListValues()::build);
|
|
BiPredicate<Multimap<?, ?>, Multimap<?, ?>> equivalence =
|
|
Equivalence.equals()
|
|
.onResultOf((Multimap<?, ?> mm) -> ImmutableList.copyOf(mm.asMap().entrySet()))
|
|
.and(Equivalence.equals());
|
|
ListMultimap<Character, Character> empty =
|
|
MultimapBuilder.linkedHashKeys().arrayListValues().build();
|
|
ListMultimap<Character, Character> filled =
|
|
MultimapBuilder.linkedHashKeys().arrayListValues().build();
|
|
filled.putAll('b', Arrays.asList('a', 'n', 'a', 'n', 'a'));
|
|
filled.putAll('a', Arrays.asList('p', 'p', 'l', 'e'));
|
|
filled.putAll('c', Arrays.asList('a', 'r', 'r', 'o', 't'));
|
|
filled.putAll('a', Arrays.asList('s', 'p', 'a', 'r', 'a', 'g', 'u', 's'));
|
|
filled.putAll('c', Arrays.asList('h', 'e', 'r', 'r', 'y'));
|
|
CollectorTester.of(collector, equivalence)
|
|
.expectCollects(empty)
|
|
.expectCollects(filled, "banana", "apple", "carrot", "asparagus", "cherry");
|
|
}
|
|
|
|
@SuppressWarnings("deprecation")
|
|
public void testUnmodifiableListMultimapShortCircuit() {
|
|
ListMultimap<String, Integer> mod = ArrayListMultimap.create();
|
|
ListMultimap<String, Integer> unmod = Multimaps.unmodifiableListMultimap(mod);
|
|
assertNotSame(mod, unmod);
|
|
assertSame(unmod, Multimaps.unmodifiableListMultimap(unmod));
|
|
ImmutableListMultimap<String, Integer> immutable =
|
|
ImmutableListMultimap.of("a", 1, "b", 2, "a", 3);
|
|
assertSame(immutable, Multimaps.unmodifiableListMultimap(immutable));
|
|
assertSame(
|
|
immutable, Multimaps.unmodifiableListMultimap((ListMultimap<String, Integer>) immutable));
|
|
}
|
|
|
|
@SuppressWarnings("deprecation")
|
|
public void testUnmodifiableSetMultimapShortCircuit() {
|
|
SetMultimap<String, Integer> mod = HashMultimap.create();
|
|
SetMultimap<String, Integer> unmod = Multimaps.unmodifiableSetMultimap(mod);
|
|
assertNotSame(mod, unmod);
|
|
assertSame(unmod, Multimaps.unmodifiableSetMultimap(unmod));
|
|
ImmutableSetMultimap<String, Integer> immutable =
|
|
ImmutableSetMultimap.of("a", 1, "b", 2, "a", 3);
|
|
assertSame(immutable, Multimaps.unmodifiableSetMultimap(immutable));
|
|
assertSame(
|
|
immutable, Multimaps.unmodifiableSetMultimap((SetMultimap<String, Integer>) immutable));
|
|
}
|
|
|
|
@SuppressWarnings("deprecation")
|
|
public void testUnmodifiableMultimapShortCircuit() {
|
|
Multimap<String, Integer> mod = HashMultimap.create();
|
|
Multimap<String, Integer> unmod = Multimaps.unmodifiableMultimap(mod);
|
|
assertNotSame(mod, unmod);
|
|
assertSame(unmod, Multimaps.unmodifiableMultimap(unmod));
|
|
ImmutableMultimap<String, Integer> immutable = ImmutableMultimap.of("a", 1, "b", 2, "a", 3);
|
|
assertSame(immutable, Multimaps.unmodifiableMultimap(immutable));
|
|
assertSame(immutable, Multimaps.unmodifiableMultimap((Multimap<String, Integer>) immutable));
|
|
}
|
|
|
|
@GwtIncompatible // slow (~10s)
|
|
public void testUnmodifiableArrayListMultimap() {
|
|
checkUnmodifiableMultimap(ArrayListMultimap.<String, Integer>create(), true);
|
|
}
|
|
|
|
@GwtIncompatible // SerializableTester
|
|
public void testSerializingUnmodifiableArrayListMultimap() {
|
|
Multimap<String, Integer> unmodifiable =
|
|
prepareUnmodifiableTests(ArrayListMultimap.<String, Integer>create(), true, null, null);
|
|
SerializableTester.reserializeAndAssert(unmodifiable);
|
|
}
|
|
|
|
public void testUnmodifiableArrayListMultimapRandomAccess() {
|
|
ListMultimap<String, Integer> delegate = ArrayListMultimap.create();
|
|
delegate.put("foo", 1);
|
|
delegate.put("foo", 3);
|
|
ListMultimap<String, Integer> multimap = Multimaps.unmodifiableListMultimap(delegate);
|
|
assertTrue(multimap.get("foo") instanceof RandomAccess);
|
|
assertTrue(multimap.get("bar") instanceof RandomAccess);
|
|
}
|
|
|
|
public void testUnmodifiableLinkedListMultimapRandomAccess() {
|
|
ListMultimap<String, Integer> delegate = LinkedListMultimap.create();
|
|
delegate.put("foo", 1);
|
|
delegate.put("foo", 3);
|
|
ListMultimap<String, Integer> multimap = Multimaps.unmodifiableListMultimap(delegate);
|
|
assertFalse(multimap.get("foo") instanceof RandomAccess);
|
|
assertFalse(multimap.get("bar") instanceof RandomAccess);
|
|
}
|
|
|
|
@GwtIncompatible // slow (~10s)
|
|
public void testUnmodifiableHashMultimap() {
|
|
checkUnmodifiableMultimap(HashMultimap.<String, Integer>create(), false);
|
|
}
|
|
|
|
@GwtIncompatible // SerializableTester
|
|
public void testSerializingUnmodifiableHashMultimap() {
|
|
Multimap<String, Integer> unmodifiable =
|
|
prepareUnmodifiableTests(HashMultimap.<String, Integer>create(), false, null, null);
|
|
SerializableTester.reserializeAndAssert(unmodifiable);
|
|
}
|
|
|
|
@GwtIncompatible // slow (~10s)
|
|
public void testUnmodifiableTreeMultimap() {
|
|
checkUnmodifiableMultimap(TreeMultimap.<String, Integer>create(), false, "null", 42);
|
|
}
|
|
|
|
@GwtIncompatible // SerializableTester
|
|
public void testSerializingUnmodifiableTreeMultimap() {
|
|
Multimap<String, Integer> unmodifiable =
|
|
prepareUnmodifiableTests(TreeMultimap.<String, Integer>create(), false, "null", 42);
|
|
SerializableTester.reserializeAndAssert(unmodifiable);
|
|
}
|
|
|
|
@GwtIncompatible // slow (~10s)
|
|
public void testUnmodifiableSynchronizedArrayListMultimap() {
|
|
checkUnmodifiableMultimap(
|
|
Multimaps.synchronizedListMultimap(ArrayListMultimap.<String, Integer>create()), true);
|
|
}
|
|
|
|
@GwtIncompatible // SerializableTester
|
|
public void testSerializingUnmodifiableSynchronizedArrayListMultimap() {
|
|
Multimap<String, Integer> unmodifiable =
|
|
prepareUnmodifiableTests(
|
|
Multimaps.synchronizedListMultimap(ArrayListMultimap.<String, Integer>create()),
|
|
true,
|
|
null,
|
|
null);
|
|
SerializableTester.reserializeAndAssert(unmodifiable);
|
|
}
|
|
|
|
@GwtIncompatible // slow (~10s)
|
|
public void testUnmodifiableSynchronizedHashMultimap() {
|
|
checkUnmodifiableMultimap(
|
|
Multimaps.synchronizedSetMultimap(HashMultimap.<String, Integer>create()), false);
|
|
}
|
|
|
|
@GwtIncompatible // SerializableTester
|
|
public void testSerializingUnmodifiableSynchronizedHashMultimap() {
|
|
Multimap<String, Integer> unmodifiable =
|
|
prepareUnmodifiableTests(
|
|
Multimaps.synchronizedSetMultimap(HashMultimap.<String, Integer>create()),
|
|
false,
|
|
null,
|
|
null);
|
|
SerializableTester.reserializeAndAssert(unmodifiable);
|
|
}
|
|
|
|
@GwtIncompatible // slow (~10s)
|
|
public void testUnmodifiableSynchronizedTreeMultimap() {
|
|
TreeMultimap<String, Integer> delegate =
|
|
TreeMultimap.create(Ordering.<String>natural(), INT_COMPARATOR);
|
|
SortedSetMultimap<String, Integer> multimap = Multimaps.synchronizedSortedSetMultimap(delegate);
|
|
checkUnmodifiableMultimap(multimap, false, "null", 42);
|
|
assertSame(INT_COMPARATOR, multimap.valueComparator());
|
|
}
|
|
|
|
@GwtIncompatible // SerializableTester
|
|
public void testSerializingUnmodifiableSynchronizedTreeMultimap() {
|
|
TreeMultimap<String, Integer> delegate =
|
|
TreeMultimap.create(Ordering.<String>natural(), INT_COMPARATOR);
|
|
SortedSetMultimap<String, Integer> multimap = Multimaps.synchronizedSortedSetMultimap(delegate);
|
|
Multimap<String, Integer> unmodifiable = prepareUnmodifiableTests(multimap, false, "null", 42);
|
|
SerializableTester.reserializeAndAssert(unmodifiable);
|
|
assertSame(INT_COMPARATOR, multimap.valueComparator());
|
|
}
|
|
|
|
public void testUnmodifiableMultimapIsView() {
|
|
Multimap<String, Integer> mod = HashMultimap.create();
|
|
Multimap<String, Integer> unmod = Multimaps.unmodifiableMultimap(mod);
|
|
assertEquals(mod, unmod);
|
|
mod.put("foo", 1);
|
|
assertTrue(unmod.containsEntry("foo", 1));
|
|
assertEquals(mod, unmod);
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
public void testUnmodifiableMultimapEntries() {
|
|
Multimap<String, Integer> mod = HashMultimap.create();
|
|
Multimap<String, Integer> unmod = Multimaps.unmodifiableMultimap(mod);
|
|
mod.put("foo", 1);
|
|
Entry<String, Integer> entry = unmod.entries().iterator().next();
|
|
try {
|
|
entry.setValue(2);
|
|
fail("UnsupportedOperationException expected");
|
|
} catch (UnsupportedOperationException expected) {
|
|
}
|
|
entry = (Entry<String, Integer>) unmod.entries().toArray()[0];
|
|
try {
|
|
entry.setValue(2);
|
|
fail("UnsupportedOperationException expected");
|
|
} catch (UnsupportedOperationException expected) {
|
|
}
|
|
Entry<String, Integer>[] array = (Entry<String, Integer>[]) new Entry<?, ?>[2];
|
|
assertSame(array, unmod.entries().toArray(array));
|
|
try {
|
|
array[0].setValue(2);
|
|
fail("UnsupportedOperationException expected");
|
|
} catch (UnsupportedOperationException expected) {
|
|
}
|
|
assertFalse(unmod.entries().contains(nefariousMapEntry("pwnd", 2)));
|
|
assertFalse(unmod.keys().contains("pwnd"));
|
|
}
|
|
|
|
/**
|
|
* The supplied multimap will be mutated and an unmodifiable instance used in its stead. The
|
|
* multimap must support null keys and values.
|
|
*/
|
|
private static void checkUnmodifiableMultimap(
|
|
Multimap<String, Integer> multimap, boolean permitsDuplicates) {
|
|
checkUnmodifiableMultimap(multimap, permitsDuplicates, null, null);
|
|
}
|
|
|
|
/**
|
|
* The supplied multimap will be mutated and an unmodifiable instance used in its stead. If the
|
|
* multimap does not support null keys or values, alternatives may be specified for tests
|
|
* involving nulls.
|
|
*/
|
|
private static void checkUnmodifiableMultimap(
|
|
Multimap<String, Integer> multimap,
|
|
boolean permitsDuplicates,
|
|
@Nullable String nullKey,
|
|
@Nullable Integer nullValue) {
|
|
Multimap<String, Integer> unmodifiable =
|
|
prepareUnmodifiableTests(multimap, permitsDuplicates, nullKey, nullValue);
|
|
|
|
UnmodifiableCollectionTests.assertMultimapIsUnmodifiable(unmodifiable, "test", 123);
|
|
|
|
assertUnmodifiableIterableInTandem(unmodifiable.keys(), multimap.keys());
|
|
|
|
assertUnmodifiableIterableInTandem(unmodifiable.keySet(), multimap.keySet());
|
|
|
|
assertUnmodifiableIterableInTandem(unmodifiable.entries(), multimap.entries());
|
|
|
|
assertUnmodifiableIterableInTandem(
|
|
unmodifiable.asMap().entrySet(), multimap.asMap().entrySet());
|
|
|
|
assertEquals(multimap.toString(), unmodifiable.toString());
|
|
assertEquals(multimap.hashCode(), unmodifiable.hashCode());
|
|
assertEquals(multimap, unmodifiable);
|
|
|
|
assertThat(unmodifiable.asMap().get("bar")).containsExactly(5, -1);
|
|
assertNull(unmodifiable.asMap().get("missing"));
|
|
|
|
assertFalse(unmodifiable.entries() instanceof Serializable);
|
|
}
|
|
|
|
/** Prepares the multimap for unmodifiable tests, returning an unmodifiable view of the map. */
|
|
private static Multimap<String, Integer> prepareUnmodifiableTests(
|
|
Multimap<String, Integer> multimap,
|
|
boolean permitsDuplicates,
|
|
@Nullable String nullKey,
|
|
@Nullable Integer nullValue) {
|
|
multimap.clear();
|
|
multimap.put("foo", 1);
|
|
multimap.put("foo", 2);
|
|
multimap.put("foo", 3);
|
|
multimap.put("bar", 5);
|
|
multimap.put("bar", -1);
|
|
multimap.put(nullKey, nullValue);
|
|
multimap.put("foo", nullValue);
|
|
multimap.put(nullKey, 5);
|
|
multimap.put("foo", 2);
|
|
|
|
if (permitsDuplicates) {
|
|
assertEquals(9, multimap.size());
|
|
} else {
|
|
assertEquals(8, multimap.size());
|
|
}
|
|
|
|
Multimap<String, Integer> unmodifiable;
|
|
if (multimap instanceof SortedSetMultimap) {
|
|
unmodifiable =
|
|
Multimaps.unmodifiableSortedSetMultimap((SortedSetMultimap<String, Integer>) multimap);
|
|
} else if (multimap instanceof SetMultimap) {
|
|
unmodifiable = Multimaps.unmodifiableSetMultimap((SetMultimap<String, Integer>) multimap);
|
|
} else if (multimap instanceof ListMultimap) {
|
|
unmodifiable = Multimaps.unmodifiableListMultimap((ListMultimap<String, Integer>) multimap);
|
|
} else {
|
|
unmodifiable = Multimaps.unmodifiableMultimap(multimap);
|
|
}
|
|
return unmodifiable;
|
|
}
|
|
|
|
private static <T> void assertUnmodifiableIterableInTandem(
|
|
Iterable<T> unmodifiable, Iterable<T> modifiable) {
|
|
UnmodifiableCollectionTests.assertIteratorIsUnmodifiable(unmodifiable.iterator());
|
|
UnmodifiableCollectionTests.assertIteratorsInOrder(
|
|
unmodifiable.iterator(), modifiable.iterator());
|
|
}
|
|
|
|
public void testInvertFrom() {
|
|
ImmutableMultimap<Integer, String> empty = ImmutableMultimap.of();
|
|
|
|
// typical usage example - sad that ArrayListMultimap.create() won't work
|
|
Multimap<String, Integer> multimap =
|
|
Multimaps.invertFrom(empty, ArrayListMultimap.<String, Integer>create());
|
|
assertTrue(multimap.isEmpty());
|
|
|
|
ImmutableMultimap<Integer, String> single =
|
|
new ImmutableMultimap.Builder<Integer, String>().put(1, "one").put(2, "two").build();
|
|
|
|
// copy into existing multimap
|
|
assertSame(multimap, Multimaps.invertFrom(single, multimap));
|
|
|
|
ImmutableMultimap<String, Integer> expected =
|
|
new ImmutableMultimap.Builder<String, Integer>().put("one", 1).put("two", 2).build();
|
|
|
|
assertEquals(expected, multimap);
|
|
}
|
|
|
|
public void testAsMap_multimap() {
|
|
Multimap<String, Integer> multimap =
|
|
Multimaps.newMultimap(new HashMap<String, Collection<Integer>>(), new QueueSupplier());
|
|
Map<String, Collection<Integer>> map = Multimaps.asMap(multimap);
|
|
assertSame(multimap.asMap(), map);
|
|
}
|
|
|
|
public void testAsMap_listMultimap() {
|
|
ListMultimap<String, Integer> listMultimap = ArrayListMultimap.create();
|
|
Map<String, List<Integer>> map = Multimaps.asMap(listMultimap);
|
|
assertSame(listMultimap.asMap(), map);
|
|
}
|
|
|
|
public void testAsMap_setMultimap() {
|
|
SetMultimap<String, Integer> setMultimap = LinkedHashMultimap.create();
|
|
Map<String, Set<Integer>> map = Multimaps.asMap(setMultimap);
|
|
assertSame(setMultimap.asMap(), map);
|
|
}
|
|
|
|
public void testAsMap_sortedSetMultimap() {
|
|
SortedSetMultimap<String, Integer> sortedSetMultimap = TreeMultimap.create();
|
|
Map<String, SortedSet<Integer>> map = Multimaps.asMap(sortedSetMultimap);
|
|
assertSame(sortedSetMultimap.asMap(), map);
|
|
}
|
|
|
|
public void testForMap() {
|
|
Map<String, Integer> map = Maps.newHashMap();
|
|
map.put("foo", 1);
|
|
map.put("bar", 2);
|
|
Multimap<String, Integer> multimap = HashMultimap.create();
|
|
multimap.put("foo", 1);
|
|
multimap.put("bar", 2);
|
|
Multimap<String, Integer> multimapView = Multimaps.forMap(map);
|
|
new EqualsTester().addEqualityGroup(multimap, multimapView).addEqualityGroup(map).testEquals();
|
|
Multimap<String, Integer> multimap2 = HashMultimap.create();
|
|
multimap2.put("foo", 1);
|
|
assertFalse(multimapView.equals(multimap2));
|
|
multimap2.put("bar", 1);
|
|
assertFalse(multimapView.equals(multimap2));
|
|
ListMultimap<String, Integer> listMultimap =
|
|
new ImmutableListMultimap.Builder<String, Integer>().put("foo", 1).put("bar", 2).build();
|
|
assertFalse("SetMultimap equals ListMultimap", multimapView.equals(listMultimap));
|
|
assertEquals(multimap.hashCode(), multimapView.hashCode());
|
|
assertEquals(multimap.size(), multimapView.size());
|
|
assertTrue(multimapView.containsKey("foo"));
|
|
assertTrue(multimapView.containsValue(1));
|
|
assertTrue(multimapView.containsEntry("bar", 2));
|
|
assertEquals(Collections.singleton(1), multimapView.get("foo"));
|
|
assertEquals(Collections.singleton(2), multimapView.get("bar"));
|
|
try {
|
|
multimapView.put("baz", 3);
|
|
fail("UnsupportedOperationException expected");
|
|
} catch (UnsupportedOperationException expected) {
|
|
}
|
|
try {
|
|
multimapView.putAll("baz", Collections.singleton(3));
|
|
fail("UnsupportedOperationException expected");
|
|
} catch (UnsupportedOperationException expected) {
|
|
}
|
|
try {
|
|
multimapView.putAll(multimap);
|
|
fail("UnsupportedOperationException expected");
|
|
} catch (UnsupportedOperationException expected) {
|
|
}
|
|
try {
|
|
multimapView.replaceValues("foo", Collections.<Integer>emptySet());
|
|
fail("UnsupportedOperationException expected");
|
|
} catch (UnsupportedOperationException expected) {
|
|
}
|
|
multimapView.remove("bar", 2);
|
|
assertFalse(multimapView.containsKey("bar"));
|
|
assertFalse(map.containsKey("bar"));
|
|
assertEquals(map.keySet(), multimapView.keySet());
|
|
assertEquals(map.keySet(), multimapView.keys().elementSet());
|
|
assertThat(multimapView.keys()).contains("foo");
|
|
assertThat(multimapView.values()).contains(1);
|
|
assertThat(multimapView.entries()).contains(Maps.immutableEntry("foo", 1));
|
|
assertThat(multimapView.asMap().entrySet())
|
|
.contains(Maps.immutableEntry("foo", (Collection<Integer>) Collections.singleton(1)));
|
|
multimapView.clear();
|
|
assertFalse(multimapView.containsKey("foo"));
|
|
assertFalse(map.containsKey("foo"));
|
|
assertTrue(map.isEmpty());
|
|
assertTrue(multimapView.isEmpty());
|
|
multimap.clear();
|
|
assertEquals(multimap.toString(), multimapView.toString());
|
|
assertEquals(multimap.hashCode(), multimapView.hashCode());
|
|
assertEquals(multimap.size(), multimapView.size());
|
|
assertEquals(multimapView, ArrayListMultimap.create());
|
|
}
|
|
|
|
@GwtIncompatible // SerializableTester
|
|
public void testForMapSerialization() {
|
|
Map<String, Integer> map = Maps.newHashMap();
|
|
map.put("foo", 1);
|
|
map.put("bar", 2);
|
|
Multimap<String, Integer> multimapView = Multimaps.forMap(map);
|
|
SerializableTester.reserializeAndAssert(multimapView);
|
|
}
|
|
|
|
public void testForMapRemoveAll() {
|
|
Map<String, Integer> map = Maps.newHashMap();
|
|
map.put("foo", 1);
|
|
map.put("bar", 2);
|
|
map.put("cow", 3);
|
|
Multimap<String, Integer> multimap = Multimaps.forMap(map);
|
|
assertEquals(3, multimap.size());
|
|
assertEquals(Collections.emptySet(), multimap.removeAll("dog"));
|
|
assertEquals(3, multimap.size());
|
|
assertTrue(multimap.containsKey("bar"));
|
|
assertEquals(Collections.singleton(2), multimap.removeAll("bar"));
|
|
assertEquals(2, multimap.size());
|
|
assertFalse(multimap.containsKey("bar"));
|
|
}
|
|
|
|
public void testForMapAsMap() {
|
|
Map<String, Integer> map = Maps.newHashMap();
|
|
map.put("foo", 1);
|
|
map.put("bar", 2);
|
|
Map<String, Collection<Integer>> asMap = Multimaps.forMap(map).asMap();
|
|
assertEquals(Collections.singleton(1), asMap.get("foo"));
|
|
assertNull(asMap.get("cow"));
|
|
assertTrue(asMap.containsKey("foo"));
|
|
assertFalse(asMap.containsKey("cow"));
|
|
|
|
Set<Entry<String, Collection<Integer>>> entries = asMap.entrySet();
|
|
assertFalse(entries.contains((Object) 4.5));
|
|
assertFalse(entries.remove((Object) 4.5));
|
|
assertFalse(entries.contains(Maps.immutableEntry("foo", Collections.singletonList(1))));
|
|
assertFalse(entries.remove(Maps.immutableEntry("foo", Collections.singletonList(1))));
|
|
assertFalse(entries.contains(Maps.immutableEntry("foo", Sets.newLinkedHashSet(asList(1, 2)))));
|
|
assertFalse(entries.remove(Maps.immutableEntry("foo", Sets.newLinkedHashSet(asList(1, 2)))));
|
|
assertFalse(entries.contains(Maps.immutableEntry("foo", Collections.singleton(2))));
|
|
assertFalse(entries.remove(Maps.immutableEntry("foo", Collections.singleton(2))));
|
|
assertTrue(map.containsKey("foo"));
|
|
assertTrue(entries.contains(Maps.immutableEntry("foo", Collections.singleton(1))));
|
|
assertTrue(entries.remove(Maps.immutableEntry("foo", Collections.singleton(1))));
|
|
assertFalse(map.containsKey("foo"));
|
|
}
|
|
|
|
public void testForMapGetIteration() {
|
|
IteratorTester<Integer> tester =
|
|
new IteratorTester<Integer>(
|
|
4, MODIFIABLE, newHashSet(1), IteratorTester.KnownOrder.KNOWN_ORDER) {
|
|
private Multimap<String, Integer> multimap;
|
|
|
|
@Override
|
|
protected Iterator<Integer> newTargetIterator() {
|
|
Map<String, Integer> map = Maps.newHashMap();
|
|
map.put("foo", 1);
|
|
map.put("bar", 2);
|
|
multimap = Multimaps.forMap(map);
|
|
return multimap.get("foo").iterator();
|
|
}
|
|
|
|
@Override
|
|
protected void verify(List<Integer> elements) {
|
|
assertEquals(newHashSet(elements), multimap.get("foo"));
|
|
}
|
|
};
|
|
|
|
tester.test();
|
|
}
|
|
|
|
private enum Color {
|
|
BLUE,
|
|
RED,
|
|
YELLOW,
|
|
GREEN
|
|
}
|
|
|
|
private abstract static class CountingSupplier<E> implements Supplier<E>, Serializable {
|
|
int count;
|
|
|
|
abstract E getImpl();
|
|
|
|
@Override
|
|
public E get() {
|
|
count++;
|
|
return getImpl();
|
|
}
|
|
}
|
|
|
|
private static class QueueSupplier extends CountingSupplier<Queue<Integer>> {
|
|
@Override
|
|
public Queue<Integer> getImpl() {
|
|
return new LinkedList<>();
|
|
}
|
|
|
|
private static final long serialVersionUID = 0;
|
|
}
|
|
|
|
public void testNewMultimapWithCollectionRejectingNegativeElements() {
|
|
CountingSupplier<Set<Integer>> factory =
|
|
new SetSupplier() {
|
|
@Override
|
|
public Set<Integer> getImpl() {
|
|
final Set<Integer> backing = super.getImpl();
|
|
return new ForwardingSet<Integer>() {
|
|
@Override
|
|
protected Set<Integer> delegate() {
|
|
return backing;
|
|
}
|
|
|
|
@Override
|
|
public boolean add(Integer element) {
|
|
checkArgument(element >= 0);
|
|
return super.add(element);
|
|
}
|
|
|
|
@Override
|
|
public boolean addAll(Collection<? extends Integer> collection) {
|
|
return standardAddAll(collection);
|
|
}
|
|
};
|
|
}
|
|
};
|
|
|
|
Map<Color, Collection<Integer>> map = Maps.newEnumMap(Color.class);
|
|
Multimap<Color, Integer> multimap = Multimaps.newMultimap(map, factory);
|
|
try {
|
|
multimap.put(Color.BLUE, -1);
|
|
fail("Expected IllegalArgumentException");
|
|
} catch (IllegalArgumentException expected) {
|
|
}
|
|
multimap.put(Color.RED, 1);
|
|
multimap.put(Color.BLUE, 2);
|
|
try {
|
|
multimap.put(Color.GREEN, -1);
|
|
fail("Expected IllegalArgumentException");
|
|
} catch (IllegalArgumentException expected) {
|
|
}
|
|
assertThat(multimap.entries())
|
|
.containsExactly(Maps.immutableEntry(Color.RED, 1), Maps.immutableEntry(Color.BLUE, 2));
|
|
}
|
|
|
|
public void testNewMultimap() {
|
|
// The ubiquitous EnumArrayBlockingQueueMultimap
|
|
CountingSupplier<Queue<Integer>> factory = new QueueSupplier();
|
|
|
|
Map<Color, Collection<Integer>> map = Maps.newEnumMap(Color.class);
|
|
Multimap<Color, Integer> multimap = Multimaps.newMultimap(map, factory);
|
|
assertEquals(0, factory.count);
|
|
multimap.putAll(Color.BLUE, asList(3, 1, 4));
|
|
assertEquals(1, factory.count);
|
|
multimap.putAll(Color.RED, asList(2, 7, 1, 8));
|
|
assertEquals(2, factory.count);
|
|
assertEquals("[3, 1, 4]", multimap.get(Color.BLUE).toString());
|
|
|
|
Multimap<Color, Integer> ummodifiable = Multimaps.unmodifiableMultimap(multimap);
|
|
assertEquals("[3, 1, 4]", ummodifiable.get(Color.BLUE).toString());
|
|
|
|
Collection<Integer> collection = multimap.get(Color.BLUE);
|
|
assertEquals(collection, collection);
|
|
|
|
assertFalse(multimap.keySet() instanceof SortedSet);
|
|
assertFalse(multimap.asMap() instanceof SortedMap);
|
|
}
|
|
|
|
public void testNewMultimapValueCollectionMatchesNavigableSet() {
|
|
Supplier<TreeSet<Integer>> factory = new SortedSetSupplier();
|
|
Map<Color, Collection<Integer>> map = Maps.newEnumMap(Color.class);
|
|
Multimap<Color, Integer> multimap = Multimaps.newMultimap(map, factory);
|
|
assertTrue(multimap.get(Color.BLUE) instanceof NavigableSet);
|
|
}
|
|
|
|
public void testNewMultimapValueCollectionMatchesList() {
|
|
Supplier<LinkedList<Integer>> factory = new ListSupplier();
|
|
Map<Color, Collection<Integer>> map = Maps.newEnumMap(Color.class);
|
|
Multimap<Color, Integer> multimap = Multimaps.newMultimap(map, factory);
|
|
assertTrue(multimap.get(Color.BLUE) instanceof List);
|
|
}
|
|
|
|
@GwtIncompatible // SerializableTester
|
|
public void testNewMultimapSerialization() {
|
|
CountingSupplier<Queue<Integer>> factory = new QueueSupplier();
|
|
Map<Color, Collection<Integer>> map = Maps.newEnumMap(Color.class);
|
|
Multimap<Color, Integer> multimap = Multimaps.newMultimap(map, factory);
|
|
multimap.putAll(Color.BLUE, asList(3, 1, 4));
|
|
multimap.putAll(Color.RED, asList(2, 7, 1, 8));
|
|
SerializableTester.reserializeAndAssert(multimap);
|
|
}
|
|
|
|
private static class ListSupplier extends CountingSupplier<LinkedList<Integer>> {
|
|
@Override
|
|
public LinkedList<Integer> getImpl() {
|
|
return new LinkedList<>();
|
|
}
|
|
|
|
private static final long serialVersionUID = 0;
|
|
}
|
|
|
|
public void testNewListMultimap() {
|
|
CountingSupplier<LinkedList<Integer>> factory = new ListSupplier();
|
|
Map<Color, Collection<Integer>> map = Maps.newTreeMap();
|
|
ListMultimap<Color, Integer> multimap = Multimaps.newListMultimap(map, factory);
|
|
assertEquals(0, factory.count);
|
|
multimap.putAll(Color.BLUE, asList(3, 1, 4, 1));
|
|
assertEquals(1, factory.count);
|
|
multimap.putAll(Color.RED, asList(2, 7, 1, 8));
|
|
assertEquals(2, factory.count);
|
|
assertEquals("{BLUE=[3, 1, 4, 1], RED=[2, 7, 1, 8]}", multimap.toString());
|
|
assertFalse(multimap.get(Color.BLUE) instanceof RandomAccess);
|
|
|
|
assertTrue(multimap.keySet() instanceof SortedSet);
|
|
assertTrue(multimap.asMap() instanceof SortedMap);
|
|
}
|
|
|
|
@GwtIncompatible // SerializableTester
|
|
public void testNewListMultimapSerialization() {
|
|
CountingSupplier<LinkedList<Integer>> factory = new ListSupplier();
|
|
Map<Color, Collection<Integer>> map = Maps.newTreeMap();
|
|
ListMultimap<Color, Integer> multimap = Multimaps.newListMultimap(map, factory);
|
|
multimap.putAll(Color.BLUE, asList(3, 1, 4, 1));
|
|
multimap.putAll(Color.RED, asList(2, 7, 1, 8));
|
|
SerializableTester.reserializeAndAssert(multimap);
|
|
}
|
|
|
|
private static class SetSupplier extends CountingSupplier<Set<Integer>> {
|
|
@Override
|
|
public Set<Integer> getImpl() {
|
|
return new HashSet<>(4);
|
|
}
|
|
|
|
private static final long serialVersionUID = 0;
|
|
}
|
|
|
|
public void testNewSetMultimap() {
|
|
CountingSupplier<Set<Integer>> factory = new SetSupplier();
|
|
Map<Color, Collection<Integer>> map = Maps.newHashMap();
|
|
SetMultimap<Color, Integer> multimap = Multimaps.newSetMultimap(map, factory);
|
|
assertEquals(0, factory.count);
|
|
multimap.putAll(Color.BLUE, asList(3, 1, 4));
|
|
assertEquals(1, factory.count);
|
|
multimap.putAll(Color.RED, asList(2, 7, 1, 8));
|
|
assertEquals(2, factory.count);
|
|
assertEquals(Sets.newHashSet(4, 3, 1), multimap.get(Color.BLUE));
|
|
}
|
|
|
|
@GwtIncompatible // SerializableTester
|
|
public void testNewSetMultimapSerialization() {
|
|
CountingSupplier<Set<Integer>> factory = new SetSupplier();
|
|
Map<Color, Collection<Integer>> map = Maps.newHashMap();
|
|
SetMultimap<Color, Integer> multimap = Multimaps.newSetMultimap(map, factory);
|
|
multimap.putAll(Color.BLUE, asList(3, 1, 4));
|
|
multimap.putAll(Color.RED, asList(2, 7, 1, 8));
|
|
SerializableTester.reserializeAndAssert(multimap);
|
|
}
|
|
|
|
private static class SortedSetSupplier extends CountingSupplier<TreeSet<Integer>> {
|
|
@Override
|
|
public TreeSet<Integer> getImpl() {
|
|
return Sets.newTreeSet(INT_COMPARATOR);
|
|
}
|
|
|
|
private static final long serialVersionUID = 0;
|
|
}
|
|
|
|
public void testNewSortedSetMultimap() {
|
|
CountingSupplier<TreeSet<Integer>> factory = new SortedSetSupplier();
|
|
Map<Color, Collection<Integer>> map = Maps.newEnumMap(Color.class);
|
|
SortedSetMultimap<Color, Integer> multimap = Multimaps.newSortedSetMultimap(map, factory);
|
|
// newSortedSetMultimap calls the factory once to determine the comparator.
|
|
assertEquals(1, factory.count);
|
|
multimap.putAll(Color.BLUE, asList(3, 1, 4));
|
|
assertEquals(2, factory.count);
|
|
multimap.putAll(Color.RED, asList(2, 7, 1, 8));
|
|
assertEquals(3, factory.count);
|
|
assertEquals("[4, 3, 1]", multimap.get(Color.BLUE).toString());
|
|
assertEquals(INT_COMPARATOR, multimap.valueComparator());
|
|
}
|
|
|
|
@GwtIncompatible // SerializableTester
|
|
public void testNewSortedSetMultimapSerialization() {
|
|
CountingSupplier<TreeSet<Integer>> factory = new SortedSetSupplier();
|
|
Map<Color, Collection<Integer>> map = Maps.newEnumMap(Color.class);
|
|
SortedSetMultimap<Color, Integer> multimap = Multimaps.newSortedSetMultimap(map, factory);
|
|
multimap.putAll(Color.BLUE, asList(3, 1, 4));
|
|
multimap.putAll(Color.RED, asList(2, 7, 1, 8));
|
|
SerializableTester.reserializeAndAssert(multimap);
|
|
assertEquals(INT_COMPARATOR, multimap.valueComparator());
|
|
}
|
|
|
|
public void testIndex() {
|
|
final Multimap<String, Object> stringToObject =
|
|
new ImmutableMultimap.Builder<String, Object>()
|
|
.put("1", 1)
|
|
.put("1", 1L)
|
|
.put("1", "1")
|
|
.put("2", 2)
|
|
.put("2", 2L)
|
|
.build();
|
|
|
|
ImmutableMultimap<String, Object> outputMap =
|
|
Multimaps.index(stringToObject.values(), Functions.toStringFunction());
|
|
assertEquals(stringToObject, outputMap);
|
|
}
|
|
|
|
public void testIndexIterator() {
|
|
final Multimap<String, Object> stringToObject =
|
|
new ImmutableMultimap.Builder<String, Object>()
|
|
.put("1", 1)
|
|
.put("1", 1L)
|
|
.put("1", "1")
|
|
.put("2", 2)
|
|
.put("2", 2L)
|
|
.build();
|
|
|
|
ImmutableMultimap<String, Object> outputMap =
|
|
Multimaps.index(stringToObject.values().iterator(), Functions.toStringFunction());
|
|
assertEquals(stringToObject, outputMap);
|
|
}
|
|
|
|
public void testIndex_ordering() {
|
|
final Multimap<Integer, String> expectedIndex =
|
|
new ImmutableListMultimap.Builder<Integer, String>()
|
|
.put(4, "Inky")
|
|
.put(6, "Blinky")
|
|
.put(5, "Pinky")
|
|
.put(5, "Pinky")
|
|
.put(5, "Clyde")
|
|
.build();
|
|
|
|
final List<String> badGuys = Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde");
|
|
final Function<String, Integer> stringLengthFunction =
|
|
new Function<String, Integer>() {
|
|
@Override
|
|
public Integer apply(String input) {
|
|
return input.length();
|
|
}
|
|
};
|
|
|
|
Multimap<Integer, String> index = Multimaps.index(badGuys, stringLengthFunction);
|
|
|
|
assertEquals(expectedIndex, index);
|
|
}
|
|
|
|
public void testIndex_nullValue() {
|
|
List<Integer> values = Arrays.asList(1, null);
|
|
try {
|
|
Multimaps.index(values, Functions.identity());
|
|
fail();
|
|
} catch (NullPointerException expected) {
|
|
}
|
|
}
|
|
|
|
public void testIndex_nullKey() {
|
|
List<Integer> values = Arrays.asList(1, 2);
|
|
try {
|
|
Multimaps.index(values, Functions.constant(null));
|
|
fail();
|
|
} catch (NullPointerException expected) {
|
|
}
|
|
}
|
|
|
|
@GwtIncompatible(value = "untested")
|
|
public void testTransformValues() {
|
|
SetMultimap<String, Integer> multimap =
|
|
ImmutableSetMultimap.of("a", 2, "b", -3, "b", 3, "a", 4, "c", 6);
|
|
Function<Integer, Integer> square =
|
|
new Function<Integer, Integer>() {
|
|
@Override
|
|
public Integer apply(Integer in) {
|
|
return in * in;
|
|
}
|
|
};
|
|
Multimap<String, Integer> transformed = Multimaps.transformValues(multimap, square);
|
|
assertThat(transformed.entries())
|
|
.containsExactly(
|
|
immutableEntry("a", 4),
|
|
immutableEntry("a", 16),
|
|
immutableEntry("b", 9),
|
|
immutableEntry("b", 9),
|
|
immutableEntry("c", 36))
|
|
.inOrder();
|
|
}
|
|
|
|
@GwtIncompatible(value = "untested")
|
|
public void testTransformValuesIsView() {
|
|
Multimap<String, String> multimap = LinkedListMultimap.create();
|
|
multimap.put("a", "a");
|
|
Multimap<String, Integer> transformed =
|
|
Multimaps.transformValues(
|
|
multimap,
|
|
new Function<String, Integer>() {
|
|
|
|
@Override
|
|
public Integer apply(String str) {
|
|
return str.length();
|
|
}
|
|
});
|
|
Entry<String, String> entry = multimap.entries().iterator().next();
|
|
entry.setValue("bbb");
|
|
assertThat(transformed.entries()).containsExactly(immutableEntry("a", 3));
|
|
}
|
|
|
|
@GwtIncompatible(value = "untested")
|
|
public void testTransformListValues() {
|
|
ListMultimap<String, Integer> multimap =
|
|
ImmutableListMultimap.of("a", 2, "b", -3, "b", 3, "a", 4, "c", 6);
|
|
Function<Integer, Integer> square =
|
|
new Function<Integer, Integer>() {
|
|
@Override
|
|
public Integer apply(Integer in) {
|
|
return in * in;
|
|
}
|
|
};
|
|
ListMultimap<String, Integer> transformed = Multimaps.transformValues(multimap, square);
|
|
assertThat(transformed.entries())
|
|
.containsExactly(
|
|
immutableEntry("a", 4),
|
|
immutableEntry("a", 16),
|
|
immutableEntry("b", 9),
|
|
immutableEntry("b", 9),
|
|
immutableEntry("c", 36))
|
|
.inOrder();
|
|
}
|
|
|
|
@GwtIncompatible(value = "untested")
|
|
public void testTransformEntries() {
|
|
SetMultimap<String, Integer> multimap = ImmutableSetMultimap.of("a", 1, "a", 4, "b", -6);
|
|
EntryTransformer<String, Integer, String> transformer =
|
|
new EntryTransformer<String, Integer, String>() {
|
|
@Override
|
|
public String transformEntry(String key, Integer value) {
|
|
return (value >= 0) ? key : "no" + key;
|
|
}
|
|
};
|
|
Multimap<String, String> transformed = Multimaps.transformEntries(multimap, transformer);
|
|
assertThat(transformed.entries())
|
|
.containsExactly(
|
|
immutableEntry("a", "a"), immutableEntry("a", "a"), immutableEntry("b", "nob"))
|
|
.inOrder();
|
|
}
|
|
|
|
@GwtIncompatible(value = "untested")
|
|
public void testTransformListEntries() {
|
|
ListMultimap<String, Integer> multimap =
|
|
ImmutableListMultimap.of("a", 1, "a", 4, "b", 6, "a", 4);
|
|
EntryTransformer<String, Integer, String> transformer =
|
|
new EntryTransformer<String, Integer, String>() {
|
|
@Override
|
|
public String transformEntry(String key, Integer value) {
|
|
return key + value;
|
|
}
|
|
};
|
|
ListMultimap<String, String> transformed = Multimaps.transformEntries(multimap, transformer);
|
|
assertEquals(ImmutableListMultimap.of("a", "a1", "a", "a4", "a", "a4", "b", "b6"), transformed);
|
|
assertEquals("{a=[a1, a4, a4], b=[b6]}", transformed.toString());
|
|
}
|
|
|
|
public <K, V> void testSynchronizedMultimapSampleCodeCompilation() {
|
|
K key = null;
|
|
|
|
Multimap<K, V> multimap = Multimaps.synchronizedMultimap(HashMultimap.<K, V>create());
|
|
Collection<V> values = multimap.get(key); // Needn't be in synchronized block
|
|
synchronized (multimap) { // Synchronizing on multimap, not values!
|
|
Iterator<V> i = values.iterator(); // Must be in synchronized block
|
|
while (i.hasNext()) {
|
|
foo(i.next());
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void foo(Object o) {}
|
|
|
|
public void testFilteredKeysSetMultimapReplaceValues() {
|
|
SetMultimap<String, Integer> multimap = LinkedHashMultimap.create();
|
|
multimap.put("foo", 1);
|
|
multimap.put("bar", 2);
|
|
multimap.put("baz", 3);
|
|
multimap.put("bar", 4);
|
|
|
|
SetMultimap<String, Integer> filtered =
|
|
Multimaps.filterKeys(multimap, Predicates.in(ImmutableSet.of("foo", "bar")));
|
|
|
|
assertEquals(ImmutableSet.of(), filtered.replaceValues("baz", ImmutableSet.<Integer>of()));
|
|
|
|
try {
|
|
filtered.replaceValues("baz", ImmutableSet.of(5));
|
|
fail("Expected IllegalArgumentException");
|
|
} catch (IllegalArgumentException expected) {
|
|
}
|
|
}
|
|
|
|
public void testFilteredKeysSetMultimapGetBadValue() {
|
|
SetMultimap<String, Integer> multimap = LinkedHashMultimap.create();
|
|
multimap.put("foo", 1);
|
|
multimap.put("bar", 2);
|
|
multimap.put("baz", 3);
|
|
multimap.put("bar", 4);
|
|
|
|
SetMultimap<String, Integer> filtered =
|
|
Multimaps.filterKeys(multimap, Predicates.in(ImmutableSet.of("foo", "bar")));
|
|
Set<Integer> bazSet = filtered.get("baz");
|
|
assertThat(bazSet).isEmpty();
|
|
try {
|
|
bazSet.add(5);
|
|
fail("Expected IllegalArgumentException");
|
|
} catch (IllegalArgumentException expected) {
|
|
}
|
|
try {
|
|
bazSet.addAll(ImmutableSet.of(6, 7));
|
|
fail("Expected IllegalArgumentException");
|
|
} catch (IllegalArgumentException expected) {
|
|
}
|
|
}
|
|
|
|
public void testFilteredKeysListMultimapGetBadValue() {
|
|
ListMultimap<String, Integer> multimap = ArrayListMultimap.create();
|
|
multimap.put("foo", 1);
|
|
multimap.put("bar", 2);
|
|
multimap.put("baz", 3);
|
|
multimap.put("bar", 4);
|
|
|
|
ListMultimap<String, Integer> filtered =
|
|
Multimaps.filterKeys(multimap, Predicates.in(ImmutableSet.of("foo", "bar")));
|
|
List<Integer> bazList = filtered.get("baz");
|
|
assertThat(bazList).isEmpty();
|
|
try {
|
|
bazList.add(5);
|
|
fail("Expected IllegalArgumentException");
|
|
} catch (IllegalArgumentException expected) {
|
|
}
|
|
try {
|
|
bazList.add(0, 6);
|
|
fail("Expected IllegalArgumentException");
|
|
} catch (IllegalArgumentException expected) {
|
|
}
|
|
try {
|
|
bazList.addAll(ImmutableList.of(7, 8));
|
|
fail("Expected IllegalArgumentException");
|
|
} catch (IllegalArgumentException expected) {
|
|
}
|
|
try {
|
|
bazList.addAll(0, ImmutableList.of(9, 10));
|
|
fail("Expected IllegalArgumentException");
|
|
} catch (IllegalArgumentException expected) {
|
|
}
|
|
}
|
|
|
|
@GwtIncompatible // NullPointerTester
|
|
public void testNullPointers() {
|
|
new NullPointerTester().testAllPublicStaticMethods(Multimaps.class);
|
|
}
|
|
}
|