11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors 31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); 51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License. 61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at 71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software 111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS, 121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and 141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License. 151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.collect; 181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkArgument; 201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkNotNull; 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkState; 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.Beta; 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible; 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtIncompatible; 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Function; 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Joiner; 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Joiner.MapJoiner; 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Objects; 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Predicate; 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Predicates; 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Supplier; 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Collections2.TransformedCollection; 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Maps.EntryTransformer; 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.IOException; 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.ObjectInputStream; 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.ObjectOutputStream; 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.Serializable; 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.AbstractCollection; 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.AbstractSet; 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collection; 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collections; 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Comparator; 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.HashSet; 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Iterator; 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.List; 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map; 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map.Entry; 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.NoSuchElementException; 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Set; 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.SortedSet; 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport javax.annotation.Nullable; 551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Provides static methods acting on or generating a {@code Multimap}. 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Jared Levy 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Robert Konigsberg 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Mike Bostock 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Louis Wasserman 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 2.0 (imported from Google Collections Library) 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible(emulated = true) 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic final class Multimaps { 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private Multimaps() {} 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a new {@code Multimap} that uses the provided map and factory. It 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * can generate a multimap based on arbitrary {@link Map} and 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Collection} classes. 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The {@code factory}-generated and {@code map} classes determine the 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap iteration order. They also specify the behavior of the 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code equals}, {@code hashCode}, and {@code toString} methods for the 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap and its returned views. However, the multimap's {@code get} 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * method returns instances of a different class than {@code factory.get()} 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * does. 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The multimap is serializable if {@code map}, {@code factory}, the 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * collections generated by {@code factory}, and the multimap contents are all 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The multimap is not threadsafe when any concurrent operations update the 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap, even if {@code map} and the instances generated by 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code factory} are. Concurrent read operations will work correctly. To 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * allow concurrent update operations, wrap the multimap with a call to 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link #synchronizedMultimap}. 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Call this method only when the simpler methods 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link ArrayListMultimap#create()}, {@link HashMultimap#create()}, 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link LinkedHashMultimap#create()}, {@link LinkedListMultimap#create()}, 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link TreeMultimap#create()}, and 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice. 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note: the multimap assumes complete ownership over of {@code map} and 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the collections returned by {@code factory}. Those objects should not be 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * manually updated and they should not use soft, weak, or phantom references. 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param map place to store the mapping from each key to its corresponding 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param factory supplier of new, empty collections that will each hold all 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values for a given key 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code map} is not empty 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> Multimap<K, V> newMultimap(Map<K, Collection<V>> map, 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Supplier<? extends Collection<V>> factory) { 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new CustomMultimap<K, V>(map, factory); 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class CustomMultimap<K, V> extends AbstractMultimap<K, V> { 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Supplier<? extends Collection<V>> factory; 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CustomMultimap(Map<K, Collection<V>> map, 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Supplier<? extends Collection<V>> factory) { 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(map); 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.factory = checkNotNull(factory); 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Collection<V> createCollection() { 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return factory.get(); 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // can't use Serialization writeMultimap and populateMultimap methods since 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // there's no way to generate the empty backing map. 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @serialData the factory and the backing map */ 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java.io.ObjectOutputStream") 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void writeObject(ObjectOutputStream stream) throws IOException { 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.defaultWriteObject(); 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.writeObject(factory); 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.writeObject(backingMap()); 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java.io.ObjectInputStream") 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") // reading data stored by writeObject 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void readObject(ObjectInputStream stream) 1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throws IOException, ClassNotFoundException { 1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.defaultReadObject(); 1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert factory = (Supplier<? extends Collection<V>>) stream.readObject(); 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject(); 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert setMap(map); 1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java serialization not supported") 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a new {@code ListMultimap} that uses the provided map and factory. 1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * It can generate a multimap based on arbitrary {@link Map} and {@link List} 1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * classes. 1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The {@code factory}-generated and {@code map} classes determine the 1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap iteration order. They also specify the behavior of the 1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code equals}, {@code hashCode}, and {@code toString} methods for the 1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap and its returned views. The multimap's {@code get}, {@code 1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * removeAll}, and {@code replaceValues} methods return {@code RandomAccess} 1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * lists if the factory does. However, the multimap's {@code get} method 1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returns instances of a different class than does {@code factory.get()}. 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The multimap is serializable if {@code map}, {@code factory}, the 1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * lists generated by {@code factory}, and the multimap contents are all 1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The multimap is not threadsafe when any concurrent operations update the 1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap, even if {@code map} and the instances generated by 1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code factory} are. Concurrent read operations will work correctly. To 1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * allow concurrent update operations, wrap the multimap with a call to 1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link #synchronizedListMultimap}. 1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Call this method only when the simpler methods 1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link ArrayListMultimap#create()} and {@link LinkedListMultimap#create()} 1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * won't suffice. 1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note: the multimap assumes complete ownership over of {@code map} and 1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the lists returned by {@code factory}. Those objects should not be manually 1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * updated, they should be empty when provided, and they should not use soft, 1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * weak, or phantom references. 1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param map place to store the mapping from each key to its corresponding 1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values 1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param factory supplier of new, empty lists that will each hold all values 1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * for a given key 1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code map} is not empty 1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> ListMultimap<K, V> newListMultimap( 1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, Collection<V>> map, final Supplier<? extends List<V>> factory) { 1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new CustomListMultimap<K, V>(map, factory); 1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class CustomListMultimap<K, V> 1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends AbstractListMultimap<K, V> { 1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Supplier<? extends List<V>> factory; 1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CustomListMultimap(Map<K, Collection<V>> map, 1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Supplier<? extends List<V>> factory) { 1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(map); 2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.factory = checkNotNull(factory); 2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected List<V> createCollection() { 2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return factory.get(); 2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @serialData the factory and the backing map */ 2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java.io.ObjectOutputStream") 2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void writeObject(ObjectOutputStream stream) throws IOException { 2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.defaultWriteObject(); 2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.writeObject(factory); 2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.writeObject(backingMap()); 2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java.io.ObjectInputStream") 2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") // reading data stored by writeObject 2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void readObject(ObjectInputStream stream) 2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throws IOException, ClassNotFoundException { 2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.defaultReadObject(); 2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert factory = (Supplier<? extends List<V>>) stream.readObject(); 2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject(); 2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert setMap(map); 2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java serialization not supported") 2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a new {@code SetMultimap} that uses the provided map and factory. 2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * It can generate a multimap based on arbitrary {@link Map} and {@link Set} 2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * classes. 2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The {@code factory}-generated and {@code map} classes determine the 2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap iteration order. They also specify the behavior of the 2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code equals}, {@code hashCode}, and {@code toString} methods for the 2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap and its returned views. However, the multimap's {@code get} 2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * method returns instances of a different class than {@code factory.get()} 2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * does. 2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The multimap is serializable if {@code map}, {@code factory}, the 2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * sets generated by {@code factory}, and the multimap contents are all 2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The multimap is not threadsafe when any concurrent operations update the 2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap, even if {@code map} and the instances generated by 2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code factory} are. Concurrent read operations will work correctly. To 2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * allow concurrent update operations, wrap the multimap with a call to 2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link #synchronizedSetMultimap}. 2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Call this method only when the simpler methods 2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link HashMultimap#create()}, {@link LinkedHashMultimap#create()}, 2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link TreeMultimap#create()}, and 2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice. 2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note: the multimap assumes complete ownership over of {@code map} and 2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the sets returned by {@code factory}. Those objects should not be manually 2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * updated and they should not use soft, weak, or phantom references. 2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param map place to store the mapping from each key to its corresponding 2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values 2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param factory supplier of new, empty sets that will each hold all values 2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * for a given key 2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code map} is not empty 2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> SetMultimap<K, V> newSetMultimap( 2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, Collection<V>> map, final Supplier<? extends Set<V>> factory) { 2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new CustomSetMultimap<K, V>(map, factory); 2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class CustomSetMultimap<K, V> 2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends AbstractSetMultimap<K, V> { 2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Supplier<? extends Set<V>> factory; 2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CustomSetMultimap(Map<K, Collection<V>> map, 2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Supplier<? extends Set<V>> factory) { 2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(map); 2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.factory = checkNotNull(factory); 2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Set<V> createCollection() { 2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return factory.get(); 2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @serialData the factory and the backing map */ 2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java.io.ObjectOutputStream") 2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void writeObject(ObjectOutputStream stream) throws IOException { 2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.defaultWriteObject(); 2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.writeObject(factory); 2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.writeObject(backingMap()); 2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java.io.ObjectInputStream") 2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") // reading data stored by writeObject 2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void readObject(ObjectInputStream stream) 2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throws IOException, ClassNotFoundException { 2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.defaultReadObject(); 2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert factory = (Supplier<? extends Set<V>>) stream.readObject(); 2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject(); 3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert setMap(map); 3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("not needed in emulated source") 3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a new {@code SortedSetMultimap} that uses the provided map and 3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * factory. It can generate a multimap based on arbitrary {@link Map} and 3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link SortedSet} classes. 3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The {@code factory}-generated and {@code map} classes determine the 3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap iteration order. They also specify the behavior of the 3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code equals}, {@code hashCode}, and {@code toString} methods for the 3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap and its returned views. However, the multimap's {@code get} 3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * method returns instances of a different class than {@code factory.get()} 3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * does. 3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The multimap is serializable if {@code map}, {@code factory}, the 3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * sets generated by {@code factory}, and the multimap contents are all 3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The multimap is not threadsafe when any concurrent operations update the 3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap, even if {@code map} and the instances generated by 3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code factory} are. Concurrent read operations will work correctly. To 3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * allow concurrent update operations, wrap the multimap with a call to 3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link #synchronizedSortedSetMultimap}. 3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Call this method only when the simpler methods 3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link TreeMultimap#create()} and 3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice. 3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note: the multimap assumes complete ownership over of {@code map} and 3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the sets returned by {@code factory}. Those objects should not be manually 3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * updated and they should not use soft, weak, or phantom references. 3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param map place to store the mapping from each key to its corresponding 3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values 3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param factory supplier of new, empty sorted sets that will each hold 3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * all values for a given key 3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code map} is not empty 3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> SortedSetMultimap<K, V> newSortedSetMultimap( 3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, Collection<V>> map, 3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Supplier<? extends SortedSet<V>> factory) { 3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new CustomSortedSetMultimap<K, V>(map, factory); 3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class CustomSortedSetMultimap<K, V> 3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends AbstractSortedSetMultimap<K, V> { 3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Supplier<? extends SortedSet<V>> factory; 3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Comparator<? super V> valueComparator; 3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CustomSortedSetMultimap(Map<K, Collection<V>> map, 3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Supplier<? extends SortedSet<V>> factory) { 3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(map); 3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.factory = checkNotNull(factory); 3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert valueComparator = factory.get().comparator(); 3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected SortedSet<V> createCollection() { 3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return factory.get(); 3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Comparator<? super V> valueComparator() { 3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return valueComparator; 3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @serialData the factory and the backing map */ 3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java.io.ObjectOutputStream") 3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void writeObject(ObjectOutputStream stream) throws IOException { 3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.defaultWriteObject(); 3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.writeObject(factory); 3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.writeObject(backingMap()); 3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java.io.ObjectInputStream") 3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") // reading data stored by writeObject 3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void readObject(ObjectInputStream stream) 3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throws IOException, ClassNotFoundException { 3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.defaultReadObject(); 3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert factory = (Supplier<? extends SortedSet<V>>) stream.readObject(); 3831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert valueComparator = factory.get().comparator(); 3841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject(); 3851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert setMap(map); 3861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("not needed in emulated source") 3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 3901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copies each key-value mapping in {@code source} into {@code dest}, with 3941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * its key and value reversed. 3951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>If {@code source} is an {@link ImmutableMultimap}, consider using 3971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link ImmutableMultimap#inverse} instead. 3981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param source any multimap 4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param dest the multimap to copy into; usually empty 4011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return {@code dest} 4021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 4031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V, M extends Multimap<K, V>> M invertFrom( 4041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multimap<? extends V, ? extends K> source, M dest) { 4051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(dest); 4061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Map.Entry<? extends V, ? extends K> entry : source.entries()) { 4071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert dest.put(entry.getValue(), entry.getKey()); 4081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return dest; 4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 4131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a synchronized (thread-safe) multimap backed by the specified 4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap. In order to guarantee serial access, it is critical that 4151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <b>all</b> access to the backing multimap is accomplished through the 4161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned multimap. 4171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>It is imperative that the user manually synchronize on the returned 4191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap when accessing any of its collection views: <pre> {@code 4201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimap<K, V> m = Multimaps.synchronizedMultimap( 4221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * HashMultimap.<K, V>create()); 4231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ... 4241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Set<K> s = m.keySet(); // Needn't be in synchronized block 4251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ... 4261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * synchronized (m) { // Synchronizing on m, not s! 4271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Iterator<K> i = s.iterator(); // Must be in synchronized block 4281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * while (i.hasNext()) { 4291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * foo(i.next()); 4301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * } 4311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * }}</pre> 4321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Failure to follow this advice may result in non-deterministic behavior. 4341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that the generated multimap's {@link Multimap#removeAll} and 4361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Multimap#replaceValues} methods return collections that aren't 4371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * synchronized. 4381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap will be serializable if the specified multimap is 4401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param multimap the multimap to be wrapped in a synchronized view 4431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a synchronized view of the specified multimap 4441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 4451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> Multimap<K, V> synchronizedMultimap( 4461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multimap<K, V> multimap) { 4471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Synchronized.multimap(multimap, null); 4481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 4511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an unmodifiable view of the specified multimap. Query operations on 4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the returned multimap "read through" to the specified multimap, and 4531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * attempts to modify the returned multimap, either directly or through the 4541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap's views, result in an {@code UnsupportedOperationException}. 4551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that the generated multimap's {@link Multimap#removeAll} and 4571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Multimap#replaceValues} methods return collections that are 4581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * modifiable. 4591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap will be serializable if the specified multimap is 4611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 4621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param delegate the multimap for which an unmodifiable view is to be 4641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned 4651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return an unmodifiable view of the specified multimap 4661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 4671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> Multimap<K, V> unmodifiableMultimap( 4681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multimap<K, V> delegate) { 4691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (delegate instanceof UnmodifiableMultimap || 4701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert delegate instanceof ImmutableMultimap) { 4711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate; 4721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new UnmodifiableMultimap<K, V>(delegate); 4741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 4771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Simply returns its argument. 4781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @deprecated no need to use this 4801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0 4811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 4821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Deprecated public static <K, V> Multimap<K, V> unmodifiableMultimap( 4831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ImmutableMultimap<K, V> delegate) { 4841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return checkNotNull(delegate); 4851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class UnmodifiableMultimap<K, V> 4881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends ForwardingMultimap<K, V> implements Serializable { 4891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Multimap<K, V> delegate; 4901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Collection<Entry<K, V>> entries; 4911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Multiset<K> keys; 4921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Set<K> keySet; 4931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Collection<V> values; 4941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Map<K, Collection<V>> map; 4951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert UnmodifiableMultimap(final Multimap<K, V> delegate) { 4971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.delegate = checkNotNull(delegate); 4981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Multimap<K, V> delegate() { 5011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate; 5021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 5051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 5061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Map<K, Collection<V>> asMap() { 5091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, Collection<V>> result = map; 5101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 5111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map<K, Collection<V>> unmodifiableMap 5121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = Collections.unmodifiableMap(delegate.asMap()); 5131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map = result = new ForwardingMap<K, Collection<V>>() { 5141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Map<K, Collection<V>> delegate() { 5151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return unmodifiableMap; 5161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, Collection<V>>> entrySet; 5191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<Map.Entry<K, Collection<V>>> entrySet() { 5211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, Collection<V>>> result = entrySet; 5221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (result == null) 5231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? entrySet 5241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = unmodifiableAsMapEntries(unmodifiableMap.entrySet()) 5251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert : result; 5261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> get(Object key) { 5291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> collection = unmodifiableMap.get(key); 5301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (collection == null) 5311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? null : unmodifiableValueCollection(collection); 5321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<Collection<V>> asMapValues; 5351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<Collection<V>> values() { 5371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<Collection<V>> result = asMapValues; 5381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (result == null) 5391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? asMapValues 5401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = new UnmodifiableAsMapValues<V>(unmodifiableMap.values()) 5411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert : result; 5421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsValue(Object o) { 5451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return values().contains(o); 5461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 5481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 5501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<Entry<K, V>> entries() { 5531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<Entry<K, V>> result = entries; 5541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 5551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entries = result = unmodifiableEntries(delegate.entries()); 5561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 5581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> get(K key) { 5611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return unmodifiableValueCollection(delegate.get(key)); 5621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Multiset<K> keys() { 5651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multiset<K> result = keys; 5661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 5671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert keys = result = Multisets.unmodifiableMultiset(delegate.keys()); 5681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 5701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<K> keySet() { 5731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<K> result = keySet; 5741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 5751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert keySet = result = Collections.unmodifiableSet(delegate.keySet()); 5761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 5781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean put(K key, V value) { 5811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 5821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean putAll(K key, Iterable<? extends V> values) { 5851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 5861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 5891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean putAll(Multimap<? extends K, ? extends V> multimap) { 5901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 5911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object key, Object value) { 5941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 5951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> removeAll(Object key) { 5981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 5991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> replaceValues( 6021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K key, Iterable<? extends V> values) { 6031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 6041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> values() { 6071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> result = values; 6081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 6091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert values = result = Collections.unmodifiableCollection(delegate.values()); 6101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 6121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 6151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class UnmodifiableAsMapValues<V> 6181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends ForwardingCollection<Collection<V>> { 6191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Collection<Collection<V>> delegate; 6201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert UnmodifiableAsMapValues(Collection<Collection<V>> delegate) { 6211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.delegate = Collections.unmodifiableCollection(delegate); 6221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Collection<Collection<V>> delegate() { 6241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate; 6251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<Collection<V>> iterator() { 6271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<Collection<V>> iterator = delegate.iterator(); 6281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Iterator<Collection<V>>() { 6291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 6301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean hasNext() { 6311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return iterator.hasNext(); 6321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 6341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Collection<V> next() { 6351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return unmodifiableValueCollection(iterator.next()); 6361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 6381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void remove() { 6391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 6401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 6421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Object[] toArray() { 6441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardToArray(); 6451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public <T> T[] toArray(T[] array) { 6471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardToArray(array); 6481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(Object o) { 6501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardContains(o); 6511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsAll(Collection<?> c) { 6531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardContainsAll(c); 6541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class UnmodifiableListMultimap<K, V> 6581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends UnmodifiableMultimap<K, V> implements ListMultimap<K, V> { 6591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert UnmodifiableListMultimap(ListMultimap<K, V> delegate) { 6601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(delegate); 6611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public ListMultimap<K, V> delegate() { 6631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (ListMultimap<K, V>) super.delegate(); 6641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public List<V> get(K key) { 6661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Collections.unmodifiableList(delegate().get(key)); 6671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public List<V> removeAll(Object key) { 6691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 6701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public List<V> replaceValues( 6721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K key, Iterable<? extends V> values) { 6731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 6741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 6761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class UnmodifiableSetMultimap<K, V> 6791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends UnmodifiableMultimap<K, V> implements SetMultimap<K, V> { 6801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert UnmodifiableSetMultimap(SetMultimap<K, V> delegate) { 6811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(delegate); 6821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public SetMultimap<K, V> delegate() { 6841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (SetMultimap<K, V>) super.delegate(); 6851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<V> get(K key) { 6871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /* 6881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Note that this doesn't return a SortedSet when delegate is a 6891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * SortedSetMultiset, unlike (SortedSet<V>) super.get(). 6901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 6911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Collections.unmodifiableSet(delegate().get(key)); 6921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<Map.Entry<K, V>> entries() { 6941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Maps.unmodifiableEntrySet(delegate().entries()); 6951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<V> removeAll(Object key) { 6971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 6981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<V> replaceValues( 7001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K key, Iterable<? extends V> values) { 7011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 7021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 7041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class UnmodifiableSortedSetMultimap<K, V> 7071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends UnmodifiableSetMultimap<K, V> implements SortedSetMultimap<K, V> { 7081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert UnmodifiableSortedSetMultimap(SortedSetMultimap<K, V> delegate) { 7091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(delegate); 7101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public SortedSetMultimap<K, V> delegate() { 7121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (SortedSetMultimap<K, V>) super.delegate(); 7131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public SortedSet<V> get(K key) { 7151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Collections.unmodifiableSortedSet(delegate().get(key)); 7161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public SortedSet<V> removeAll(Object key) { 7181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 7191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public SortedSet<V> replaceValues( 7211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K key, Iterable<? extends V> values) { 7221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 7231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 7251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Comparator<? super V> valueComparator() { 7261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate().valueComparator(); 7271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 7291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 7321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a synchronized (thread-safe) {@code SetMultimap} backed by the 7331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * specified multimap. 7341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>You must follow the warnings described in {@link #synchronizedMultimap}. 7361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap will be serializable if the specified multimap is 7381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 7391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param multimap the multimap to be wrapped 7411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a synchronized view of the specified multimap 7421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 7431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> SetMultimap<K, V> synchronizedSetMultimap( 7441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SetMultimap<K, V> multimap) { 7451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Synchronized.setMultimap(multimap, null); 7461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 7491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an unmodifiable view of the specified {@code SetMultimap}. Query 7501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * operations on the returned multimap "read through" to the specified 7511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap, and attempts to modify the returned multimap, either directly or 7521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * through the multimap's views, result in an 7531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code UnsupportedOperationException}. 7541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that the generated multimap's {@link Multimap#removeAll} and 7561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Multimap#replaceValues} methods return collections that are 7571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * modifiable. 7581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap will be serializable if the specified multimap is 7601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 7611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param delegate the multimap for which an unmodifiable view is to be 7631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned 7641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return an unmodifiable view of the specified multimap 7651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 7661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> SetMultimap<K, V> unmodifiableSetMultimap( 7671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SetMultimap<K, V> delegate) { 7681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (delegate instanceof UnmodifiableSetMultimap || 7691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert delegate instanceof ImmutableSetMultimap) { 7701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate; 7711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new UnmodifiableSetMultimap<K, V>(delegate); 7731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 7761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Simply returns its argument. 7771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @deprecated no need to use this 7791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0 7801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 7811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Deprecated public static <K, V> SetMultimap<K, V> unmodifiableSetMultimap( 7821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ImmutableSetMultimap<K, V> delegate) { 7831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return checkNotNull(delegate); 7841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 7871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a synchronized (thread-safe) {@code SortedSetMultimap} backed by 7881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the specified multimap. 7891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>You must follow the warnings described in {@link #synchronizedMultimap}. 7911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap will be serializable if the specified multimap is 7931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 7941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param multimap the multimap to be wrapped 7961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a synchronized view of the specified multimap 7971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 7981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> SortedSetMultimap<K, V> 7991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert synchronizedSortedSetMultimap(SortedSetMultimap<K, V> multimap) { 8001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Synchronized.sortedSetMultimap(multimap, null); 8011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 8041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an unmodifiable view of the specified {@code SortedSetMultimap}. 8051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Query operations on the returned multimap "read through" to the specified 8061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap, and attempts to modify the returned multimap, either directly or 8071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * through the multimap's views, result in an 8081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code UnsupportedOperationException}. 8091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that the generated multimap's {@link Multimap#removeAll} and 8111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Multimap#replaceValues} methods return collections that are 8121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * modifiable. 8131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap will be serializable if the specified multimap is 8151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 8161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param delegate the multimap for which an unmodifiable view is to be 8181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned 8191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return an unmodifiable view of the specified multimap 8201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 8211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> SortedSetMultimap<K, V> unmodifiableSortedSetMultimap( 8221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedSetMultimap<K, V> delegate) { 8231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (delegate instanceof UnmodifiableSortedSetMultimap) { 8241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate; 8251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new UnmodifiableSortedSetMultimap<K, V>(delegate); 8271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 8301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a synchronized (thread-safe) {@code ListMultimap} backed by the 8311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * specified multimap. 8321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>You must follow the warnings described in {@link #synchronizedMultimap}. 8341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param multimap the multimap to be wrapped 8361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a synchronized view of the specified multimap 8371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 8381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> ListMultimap<K, V> synchronizedListMultimap( 8391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ListMultimap<K, V> multimap) { 8401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Synchronized.listMultimap(multimap, null); 8411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 8441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an unmodifiable view of the specified {@code ListMultimap}. Query 8451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * operations on the returned multimap "read through" to the specified 8461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap, and attempts to modify the returned multimap, either directly or 8471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * through the multimap's views, result in an 8481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code UnsupportedOperationException}. 8491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that the generated multimap's {@link Multimap#removeAll} and 8511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Multimap#replaceValues} methods return collections that are 8521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * modifiable. 8531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap will be serializable if the specified multimap is 8551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 8561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param delegate the multimap for which an unmodifiable view is to be 8581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned 8591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return an unmodifiable view of the specified multimap 8601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 8611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> ListMultimap<K, V> unmodifiableListMultimap( 8621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ListMultimap<K, V> delegate) { 8631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (delegate instanceof UnmodifiableListMultimap || 8641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert delegate instanceof ImmutableListMultimap) { 8651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate; 8661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new UnmodifiableListMultimap<K, V>(delegate); 8681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 8711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Simply returns its argument. 8721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @deprecated no need to use this 8741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0 8751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 8761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Deprecated public static <K, V> ListMultimap<K, V> unmodifiableListMultimap( 8771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ImmutableListMultimap<K, V> delegate) { 8781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return checkNotNull(delegate); 8791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 8821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an unmodifiable view of the specified collection, preserving the 8831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * interface for instances of {@code SortedSet}, {@code Set}, {@code List} and 8841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code Collection}, in that order of preference. 8851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param collection the collection for which to return an unmodifiable view 8871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return an unmodifiable view of the collection 8881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 8891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <V> Collection<V> unmodifiableValueCollection( 8901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> collection) { 8911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (collection instanceof SortedSet) { 8921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Collections.unmodifiableSortedSet((SortedSet<V>) collection); 8931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (collection instanceof Set) { 8941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Collections.unmodifiableSet((Set<V>) collection); 8951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (collection instanceof List) { 8961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Collections.unmodifiableList((List<V>) collection); 8971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Collections.unmodifiableCollection(collection); 8991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 9021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an unmodifiable view of the specified multimap {@code asMap} entry. 9031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * The {@link Entry#setValue} operation throws an {@link 9041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * UnsupportedOperationException}, and the collection returned by {@code 9051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * getValue} is also an unmodifiable (type-preserving) view. This also has the 9061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * side-effect of redefining equals to comply with the Map.Entry contract, and 9071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * to avoid a possible nefarious implementation of equals. 9081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 9091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param entry the entry for which to return an unmodifiable view 9101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return an unmodifiable view of the entry 9111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 9121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <K, V> Map.Entry<K, Collection<V>> unmodifiableAsMapEntry( 9131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map.Entry<K, Collection<V>> entry) { 9141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(entry); 9151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new AbstractMapEntry<K, Collection<V>>() { 9161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public K getKey() { 9171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entry.getKey(); 9181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> getValue() { 9211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return unmodifiableValueCollection(entry.getValue()); 9221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 9241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 9271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an unmodifiable view of the specified collection of entries. The 9281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Entry#setValue} operation throws an {@link 9291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * UnsupportedOperationException}. If the specified collection is a {@code 9301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Set}, the returned collection is also a {@code Set}. 9311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 9321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param entries the entries for which to return an unmodifiable view 9331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return an unmodifiable view of the entries 9341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 9351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <K, V> Collection<Entry<K, V>> unmodifiableEntries( 9361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<Entry<K, V>> entries) { 9371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (entries instanceof Set) { 9381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Maps.unmodifiableEntrySet((Set<Entry<K, V>>) entries); 9391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Maps.UnmodifiableEntries<K, V>( 9411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collections.unmodifiableCollection(entries)); 9421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 9451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an unmodifiable view of the specified set of {@code asMap} entries. 9461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * The {@link Entry#setValue} operation throws an {@link 9471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * UnsupportedOperationException}, as do any operations that attempt to modify 9481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the returned collection. 9491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 9501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param asMapEntries the {@code asMap} entries for which to return an 9511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * unmodifiable view 9521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return an unmodifiable view of the collection entries 9531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 9541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <K, V> Set<Entry<K, Collection<V>>> unmodifiableAsMapEntries( 9551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, Collection<V>>> asMapEntries) { 9561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new UnmodifiableAsMapEntries<K, V>( 9571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collections.unmodifiableSet(asMapEntries)); 9581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @see Multimaps#unmodifiableAsMapEntries */ 9611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static class UnmodifiableAsMapEntries<K, V> 9621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends ForwardingSet<Entry<K, Collection<V>>> { 9631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final Set<Entry<K, Collection<V>>> delegate; 9641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert UnmodifiableAsMapEntries(Set<Entry<K, Collection<V>>> delegate) { 9651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.delegate = delegate; 9661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Set<Entry<K, Collection<V>>> delegate() { 9691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate; 9701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<Entry<K, Collection<V>>> iterator() { 9731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<Entry<K, Collection<V>>> iterator = delegate.iterator(); 9741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ForwardingIterator<Entry<K, Collection<V>>>() { 9751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Iterator<Entry<K, Collection<V>>> delegate() { 9761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return iterator; 9771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Entry<K, Collection<V>> next() { 9791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return unmodifiableAsMapEntry(iterator.next()); 9801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 9821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Object[] toArray() { 9851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardToArray(); 9861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public <T> T[] toArray(T[] array) { 9891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardToArray(array); 9901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(Object o) { 9931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Maps.containsEntryImpl(delegate(), o); 9941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsAll(Collection<?> c) { 9971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardContainsAll(c); 9981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean equals(@Nullable Object object) { 10011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardEquals(object); 10021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 10061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a multimap view of the specified map. The multimap is backed by the 10071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * map, so changes to the map are reflected in the multimap, and vice versa. 10081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * If the map is modified while an iteration over one of the multimap's 10091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * collection views is in progress (except through the iterator's own {@code 10101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * remove} operation, or through the {@code setValue} operation on a map entry 10111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned by the iterator), the results of the iteration are undefined. 10121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The multimap supports mapping removal, which removes the corresponding 10141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * mapping from the map. It does not support any operations which might add 10151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * mappings, such as {@code put}, {@code putAll} or {@code replaceValues}. 10161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap will be serializable if the specified map is 10181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 10191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param map the backing map for the returned multimap view 10211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 10221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> SetMultimap<K, V> forMap(Map<K, V> map) { 10231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new MapMultimap<K, V>(map); 10241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @see Multimaps#forMap */ 10271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class MapMultimap<K, V> 10281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert implements SetMultimap<K, V>, Serializable { 10291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map<K, V> map; 10301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Map<K, Collection<V>> asMap; 10311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MapMultimap(Map<K, V> map) { 10331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.map = checkNotNull(map); 10341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 10371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public int size() { 10381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.size(); 10391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 10421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean isEmpty() { 10431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.isEmpty(); 10441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 10471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean containsKey(Object key) { 10481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.containsKey(key); 10491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 10521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean containsValue(Object value) { 10531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.containsValue(value); 10541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 10571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean containsEntry(Object key, Object value) { 10581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.entrySet().contains(Maps.immutableEntry(key, value)); 10591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 10621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Set<V> get(final K key) { 10631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new AbstractSet<V>() { 10641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<V> iterator() { 10651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Iterator<V>() { 10661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int i; 10671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 10691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean hasNext() { 10701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (i == 0) && map.containsKey(key); 10711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 10741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V next() { 10751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!hasNext()) { 10761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new NoSuchElementException(); 10771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert i++; 10791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.get(key); 10801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 10831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void remove() { 10841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(i == 1); 10851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert i = -1; 10861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.remove(key); 10871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 10891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 10921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.containsKey(key) ? 1 : 0; 10931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 10951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 10981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean put(K key, V value) { 10991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 11001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 11031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean putAll(K key, Iterable<? extends V> values) { 11041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 11051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 11081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean putAll(Multimap<? extends K, ? extends V> multimap) { 11091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 11101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 11131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Set<V> replaceValues(K key, Iterable<? extends V> values) { 11141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 11151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 11181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean remove(Object key, Object value) { 11191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.entrySet().remove(Maps.immutableEntry(key, value)); 11201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 11231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Set<V> removeAll(Object key) { 11241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<V> values = new HashSet<V>(2); 11251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!map.containsKey(key)) { 11261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return values; 11271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert values.add(map.remove(key)); 11291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return values; 11301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 11331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void clear() { 11341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.clear(); 11351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 11381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Set<K> keySet() { 11391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.keySet(); 11401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 11431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Multiset<K> keys() { 11441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Multisets.forSet(map.keySet()); 11451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 11481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Collection<V> values() { 11491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.values(); 11501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 11531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Set<Entry<K, V>> entries() { 11541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.entrySet(); 11551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 11581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Map<K, Collection<V>> asMap() { 11591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, Collection<V>> result = asMap; 11601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 11611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert asMap = result = new AsMap(); 11621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 11641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean equals(@Nullable Object object) { 11671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (object == this) { 11681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 11691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (object instanceof Multimap) { 11711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multimap<?, ?> that = (Multimap<?, ?>) object; 11721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this.size() == that.size() && asMap().equals(that.asMap()); 11731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 11751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int hashCode() { 11781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.hashCode(); 11791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final MapJoiner JOINER 11821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = Joiner.on("], ").withKeyValueSeparator("=[").useForNull("null"); 11831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public String toString() { 11851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.isEmpty()) { 11861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return "{}"; 11871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert StringBuilder builder 11891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = Collections2.newStringBuilderForCollection(map.size()).append('{'); 11901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert JOINER.appendTo(builder, map); 11911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return builder.append("]}").toString(); 11921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @see MapMultimap#asMap */ 11951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class AsMapEntries extends AbstractSet<Entry<K, Collection<V>>> { 11961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 11971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.size(); 11981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<Entry<K, Collection<V>>> iterator() { 12011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Iterator<Entry<K, Collection<V>>>() { 12021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<K> keys = map.keySet().iterator(); 12031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 12051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean hasNext() { 12061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return keys.hasNext(); 12071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 12091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Entry<K, Collection<V>> next() { 12101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final K key = keys.next(); 12111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new AbstractMapEntry<K, Collection<V>>() { 12121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public K getKey() { 12131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return key; 12141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> getValue() { 12161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return get(key); 12171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 12191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 12211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void remove() { 12221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert keys.remove(); 12231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 12251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(Object o) { 12281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!(o instanceof Entry)) { 12291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 12301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<?, ?> entry = (Entry<?, ?>) o; 12321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!(entry.getValue() instanceof Set)) { 12331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 12341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<?> set = (Set<?>) entry.getValue(); 12361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (set.size() == 1) 12371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && containsEntry(entry.getKey(), set.iterator().next()); 12381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object o) { 12411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!(o instanceof Entry)) { 12421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 12431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<?, ?> entry = (Entry<?, ?>) o; 12451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!(entry.getValue() instanceof Set)) { 12461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 12471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<?> set = (Set<?>) entry.getValue(); 12491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (set.size() == 1) 12501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && map.entrySet().remove( 12511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Maps.immutableEntry(entry.getKey(), set.iterator().next())); 12521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @see MapMultimap#asMap */ 12561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class AsMap extends Maps.ImprovedAbstractMap<K, Collection<V>> { 12571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Set<Entry<K, Collection<V>>> createEntrySet() { 12581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new AsMapEntries(); 12591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // The following methods are included for performance. 12621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsKey(Object key) { 12641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.containsKey(key); 12651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 12681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> get(Object key) { 12691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> collection = MapMultimap.this.get((K) key); 12701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return collection.isEmpty() ? null : collection; 12711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> remove(Object key) { 12741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> collection = removeAll(key); 12751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return collection.isEmpty() ? null : collection; 12761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 7845222491160860175L; 12791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 12821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a view of a multimap where each value is transformed by a function. 12831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * All other properties of the multimap, such as iteration order, are left 12841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * intact. For example, the code: <pre> {@code 12851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 12861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimap<String, Integer> multimap = 12871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableSetMultimap.of("a", 2, "b", -3, "b", -3, "a", 4, "c", 6); 12881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Function<Integer, String> square = new Function<Integer, String>() { 12891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * public String apply(Integer in) { 12901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * return Integer.toString(in * in); 12911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * } 12921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * }; 12931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimap<String, String> transformed = 12941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimaps.transformValues(multimap, square); 12951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * System.out.println(transformed);}</pre> 12961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 12971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ... prints {@code {a=[4, 16], b=[9, 9], c=[6]}}. 12981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 12991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Changes in the underlying multimap are reflected in this view. 13001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Conversely, this view supports removal operations, and these are reflected 13011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * in the underlying multimap. 13021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>It's acceptable for the underlying multimap to contain null keys, and 13041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * even null values provided that the function is capable of accepting null 13051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * input. The transformed multimap might contain null values, if the function 13061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * sometimes gives a null result. 13071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap is not thread-safe or serializable, even if the 13091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * underlying multimap is. The {@code equals} and {@code hashCode} methods 13101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * of the returned multimap are meaningless, since there is not a definition 13111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * of {@code equals} or {@code hashCode} for general collections, and 13121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code get()} will return a general {@code Collection} as opposed to a 13131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code List} or a {@code Set}. 13141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The function is applied lazily, invoked when needed. This is necessary 13161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * for the returned multimap to be a view, but it means that the function will 13171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * be applied many times for bulk operations like 13181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Multimap#containsValue} and {@code Multimap.toString()}. For this to 13191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * perform well, {@code function} should be fast. To avoid lazy evaluation 13201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * when the returned multimap doesn't need to be a view, copy the returned 13211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap into a new multimap of your choosing. 13221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 7.0 13241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 13251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Beta 13261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V1, V2> Multimap<K, V2> transformValues( 13271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multimap<K, V1> fromMultimap, final Function<? super V1, V2> function) { 13281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(function); 13291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryTransformer<K, V1, V2> transformer = 13301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new EntryTransformer<K, V1, V2>() { 13311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 13321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V2 transformEntry(K key, V1 value) { 13331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return function.apply(value); 13341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 13351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 13361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transformEntries(fromMultimap, transformer); 13371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 13381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 13391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 13401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a view of a multimap whose values are derived from the original 13411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap's entries. In contrast to {@link #transformValues}, this method's 13421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * entry-transformation logic may depend on the key as well as the value. 13431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>All other properties of the transformed multimap, such as iteration 13451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * order, are left intact. For example, the code: <pre> {@code 13461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * SetMultimap<String, Integer> multimap = 13481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableSetMultimap.of("a", 1, "a", 4, "b", -6); 13491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * EntryTransformer<String, Integer, String> transformer = 13501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * new EntryTransformer<String, Integer, String>() { 13511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * public String transformEntry(String key, Integer value) { 13521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * return (value >= 0) ? key : "no" + key; 13531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * } 13541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * }; 13551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimap<String, String> transformed = 13561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimaps.transformEntries(multimap, transformer); 13571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * System.out.println(transformed);}</pre> 13581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ... prints {@code {a=[a, a], b=[nob]}}. 13601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Changes in the underlying multimap are reflected in this view. 13621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Conversely, this view supports removal operations, and these are reflected 13631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * in the underlying multimap. 13641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>It's acceptable for the underlying multimap to contain null keys and 13661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * null values provided that the transformer is capable of accepting null 13671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * inputs. The transformed multimap might contain null values if the 13681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * transformer sometimes gives a null result. 13691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap is not thread-safe or serializable, even if the 13711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * underlying multimap is. The {@code equals} and {@code hashCode} methods 13721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * of the returned multimap are meaningless, since there is not a definition 13731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * of {@code equals} or {@code hashCode} for general collections, and 13741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code get()} will return a general {@code Collection} as opposed to a 13751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code List} or a {@code Set}. 13761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The transformer is applied lazily, invoked when needed. This is 13781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * necessary for the returned multimap to be a view, but it means that the 13791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * transformer will be applied many times for bulk operations like {@link 13801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimap#containsValue} and {@link Object#toString}. For this to perform 13811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * well, {@code transformer} should be fast. To avoid lazy evaluation when the 13821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned multimap doesn't need to be a view, copy the returned multimap 13831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * into a new multimap of your choosing. 13841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> This method assumes that for any instance {@code k} of 13861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies 13871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * that {@code k2} is also of type {@code K}. Using an {@code 13881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * EntryTransformer} key type for which this may not hold, such as {@code 13891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ArrayList}, may risk a {@code ClassCastException} when calling methods on 13901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the transformed multimap. 13911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 7.0 13931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 13941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Beta 13951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V1, V2> Multimap<K, V2> transformEntries( 13961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multimap<K, V1> fromMap, 13971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryTransformer<? super K, ? super V1, V2> transformer) { 13981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new TransformedEntriesMultimap<K, V1, V2>(fromMap, transformer); 13991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class TransformedEntriesMultimap<K, V1, V2> 14021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert implements Multimap<K, V2> { 14031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Multimap<K, V1> fromMultimap; 14041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final EntryTransformer<? super K, ? super V1, V2> transformer; 14051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert TransformedEntriesMultimap(Multimap<K, V1> fromMultimap, 14071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final EntryTransformer<? super K, ? super V1, V2> transformer) { 14081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.fromMultimap = checkNotNull(fromMultimap); 14091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.transformer = checkNotNull(transformer); 14101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V2> transform(final K key, Collection<V1> values) { 14131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Collections2.transform(values, new Function<V1, V2>() { 14141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V2 apply(V1 value) { 14151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transformer.transformEntry(key, value); 14161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }); 14181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private transient Map<K, Collection<V2>> asMap; 14211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Map<K, Collection<V2>> asMap() { 14231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (asMap == null) { 14241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, Collection<V2>> aM = Maps.transformEntries(fromMultimap.asMap(), 14251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new EntryTransformer<K, Collection<V1>, Collection<V2>>() { 14261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V2> transformEntry( 14281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K key, Collection<V1> value) { 14291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transform(key, value); 14301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }); 14321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert asMap = aM; 14331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return aM; 14341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return asMap; 14361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 14391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fromMultimap.clear(); 14401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 14431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsEntry(Object key, Object value) { 14441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V2> values = get((K) key); 14451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return values.contains(value); 14461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsKey(Object key) { 14491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMultimap.containsKey(key); 14501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsValue(Object value) { 14531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return values().contains(value); 14541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private transient Collection<Entry<K, V2>> entries; 14571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<Entry<K, V2>> entries() { 14591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (entries == null) { 14601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<Entry<K, V2>> es = new TransformedEntries(transformer); 14611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entries = es; 14621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return es; 14631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entries; 14651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class TransformedEntries 14681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends TransformedCollection<Entry<K, V1>, Entry<K, V2>> { 14691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert TransformedEntries( 14711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final EntryTransformer<? super K, ? super V1, V2> transformer) { 14721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(fromMultimap.entries(), 14731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new Function<Entry<K, V1>, Entry<K, V2>>() { 14741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Entry<K, V2> apply(final Entry<K, V1> entry) { 14751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new AbstractMapEntry<K, V2>() { 14761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public K getKey() { 14781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entry.getKey(); 14791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V2 getValue() { 14821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transformer.transformEntry( 14831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.getKey(), entry.getValue()); 14841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 14861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }); 14881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(Object o) { 14911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (o instanceof Entry) { 14921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<?, ?> entry = (Entry<?, ?>) o; 14931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return containsEntry(entry.getKey(), entry.getValue()); 14941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 14961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 14991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object o) { 15001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (o instanceof Entry) { 15011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<?, ?> entry = (Entry<?, ?>) o; 15021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V2> values = get((K) entry.getKey()); 15031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return values.remove(entry.getValue()); 15041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 15061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V2> get(final K key) { 15111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transform(key, fromMultimap.get(key)); 15121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean isEmpty() { 15151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMultimap.isEmpty(); 15161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<K> keySet() { 15191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMultimap.keySet(); 15201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Multiset<K> keys() { 15231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMultimap.keys(); 15241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean put(K key, V2 value) { 15271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 15281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean putAll(K key, Iterable<? extends V2> values) { 15311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 15321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean putAll( 15351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multimap<? extends K, ? extends V2> multimap) { 15361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 15371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 15401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object key, Object value) { 15411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return get((K) key).remove(value); 15421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 15451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V2> removeAll(Object key) { 15461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transform((K) key, fromMultimap.removeAll(key)); 15471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V2> replaceValues( 15501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K key, Iterable<? extends V2> values) { 15511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 15521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 15551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMultimap.size(); 15561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private transient Collection<V2> values; 15591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V2> values() { 15611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (values == null) { 15621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V2> vs = Collections2.transform( 15631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fromMultimap.entries(), new Function<Entry<K, V1>, V2>() { 15641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V2 apply(Entry<K, V1> entry) { 15661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transformer.transformEntry( 15671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.getKey(), entry.getValue()); 15681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }); 15701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert values = vs; 15711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return vs; 15721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return values; 15741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean equals(Object obj) { 15771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (obj instanceof Multimap) { 15781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multimap<?, ?> other = (Multimap<?, ?>) obj; 15791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return asMap().equals(other.asMap()); 15801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 15821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int hashCode() { 15851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return asMap().hashCode(); 15861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public String toString() { 15891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return asMap().toString(); 15901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 15941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a view of a {@code ListMultimap} where each value is transformed by 15951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * a function. All other properties of the multimap, such as iteration order, 15961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * are left intact. For example, the code: <pre> {@code 15971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 15981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ListMultimap<String, Integer> multimap 15991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * = ImmutableListMultimap.of("a", 4, "a", 16, "b", 9); 16001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Function<Integer, Double> sqrt = 16011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * new Function<Integer, Double>() { 16021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * public Double apply(Integer in) { 16031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * return Math.sqrt((int) in); 16041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * } 16051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * }; 16061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ListMultimap<String, Double> transformed = Multimaps.transformValues(map, 16071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * sqrt); 16081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * System.out.println(transformed);}</pre> 16091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ... prints {@code {a=[2.0, 4.0], b=[3.0]}}. 16111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Changes in the underlying multimap are reflected in this view. 16131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Conversely, this view supports removal operations, and these are reflected 16141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * in the underlying multimap. 16151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>It's acceptable for the underlying multimap to contain null keys, and 16171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * even null values provided that the function is capable of accepting null 16181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * input. The transformed multimap might contain null values, if the function 16191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * sometimes gives a null result. 16201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap is not thread-safe or serializable, even if the 16221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * underlying multimap is. 16231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The function is applied lazily, invoked when needed. This is necessary 16251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * for the returned multimap to be a view, but it means that the function will 16261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * be applied many times for bulk operations like 16271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Multimap#containsValue} and {@code Multimap.toString()}. For this to 16281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * perform well, {@code function} should be fast. To avoid lazy evaluation 16291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * when the returned multimap doesn't need to be a view, copy the returned 16301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap into a new multimap of your choosing. 16311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 7.0 16331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 16341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Beta 16351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V1, V2> ListMultimap<K, V2> transformValues( 16361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ListMultimap<K, V1> fromMultimap, 16371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Function<? super V1, V2> function) { 16381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(function); 16391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryTransformer<K, V1, V2> transformer = 16401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new EntryTransformer<K, V1, V2>() { 16411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 16421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V2 transformEntry(K key, V1 value) { 16431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return function.apply(value); 16441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 16461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transformEntries(fromMultimap, transformer); 16471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 16501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a view of a {@code ListMultimap} whose values are derived from the 16511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * original multimap's entries. In contrast to 16521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link #transformValues(ListMultimap, Function)}, this method's 16531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * entry-transformation logic may depend on the key as well as the value. 16541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>All other properties of the transformed multimap, such as iteration 16561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * order, are left intact. For example, the code: <pre> {@code 16571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimap<String, Integer> multimap = 16591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableMultimap.of("a", 1, "a", 4, "b", 6); 16601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * EntryTransformer<String, Integer, String> transformer = 16611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * new EntryTransformer<String, Integer, String>() { 16621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * public String transformEntry(String key, Integer value) { 16631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * return key + value; 16641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * } 16651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * }; 16661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimap<String, String> transformed = 16671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimaps.transformEntries(multimap, transformer); 16681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * System.out.println(transformed);}</pre> 16691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ... prints {@code {"a"=["a1", "a4"], "b"=["b6"]}}. 16711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Changes in the underlying multimap are reflected in this view. 16731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Conversely, this view supports removal operations, and these are reflected 16741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * in the underlying multimap. 16751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>It's acceptable for the underlying multimap to contain null keys and 16771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * null values provided that the transformer is capable of accepting null 16781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * inputs. The transformed multimap might contain null values if the 16791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * transformer sometimes gives a null result. 16801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap is not thread-safe or serializable, even if the 16821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * underlying multimap is. 16831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The transformer is applied lazily, invoked when needed. This is 16851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * necessary for the returned multimap to be a view, but it means that the 16861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * transformer will be applied many times for bulk operations like {@link 16871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimap#containsValue} and {@link Object#toString}. For this to perform 16881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * well, {@code transformer} should be fast. To avoid lazy evaluation when the 16891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned multimap doesn't need to be a view, copy the returned multimap 16901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * into a new multimap of your choosing. 16911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> This method assumes that for any instance {@code k} of 16931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies 16941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * that {@code k2} is also of type {@code K}. Using an {@code 16951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * EntryTransformer} key type for which this may not hold, such as {@code 16961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ArrayList}, may risk a {@code ClassCastException} when calling methods on 16971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the transformed multimap. 16981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 16991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 7.0 17001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 17011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Beta 17021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V1, V2> ListMultimap<K, V2> transformEntries( 17031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ListMultimap<K, V1> fromMap, 17041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryTransformer<? super K, ? super V1, V2> transformer) { 17051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new TransformedEntriesListMultimap<K, V1, V2>(fromMap, transformer); 17061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final class TransformedEntriesListMultimap<K, V1, V2> 17091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends TransformedEntriesMultimap<K, V1, V2> 17101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert implements ListMultimap<K, V2> { 17111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert TransformedEntriesListMultimap(ListMultimap<K, V1> fromMultimap, 17131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryTransformer<? super K, ? super V1, V2> transformer) { 17141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(fromMultimap, transformer); 17151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override List<V2> transform(final K key, Collection<V1> values) { 17181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Lists.transform((List<V1>) values, new Function<V1, V2>() { 17191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V2 apply(V1 value) { 17201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transformer.transformEntry(key, value); 17211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }); 17231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public List<V2> get(K key) { 17261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transform(key, fromMultimap.get(key)); 17271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 17301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public List<V2> removeAll(Object key) { 17311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transform((K) key, fromMultimap.removeAll(key)); 17321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public List<V2> replaceValues( 17351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K key, Iterable<? extends V2> values) { 17361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 17371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 17411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates an index {@code ImmutableListMultimap} that contains the results of 17421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * applying a specified function to each item in an {@code Iterable} of 17431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values. Each value will be stored as a value in the resulting multimap, 17441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * yielding a multimap with the same size as the input iterable. The key used 17451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * to store that value in the multimap will be the result of calling the 17461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * function on that value. The resulting multimap is created as an immutable 17471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * snapshot. In the returned multimap, keys appear in the order they are first 17481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * encountered, and the values corresponding to each key appear in the same 17491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * order as they are encountered. 17501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 17511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>For example, <pre> {@code 17521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 17531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * List<String> badGuys = 17541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde"); 17551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Function<String, Integer> stringLengthFunction = ...; 17561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimap<Integer, String> index = 17571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimaps.index(badGuys, stringLengthFunction); 17581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * System.out.println(index);}</pre> 17591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 17601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * prints <pre> {@code 17611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 17621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {4=[Inky], 6=[Blinky], 5=[Pinky, Pinky, Clyde]}}</pre> 17631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 17641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * The returned multimap is serializable if its keys and values are all 17651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 17661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 17671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param values the values to use when constructing the {@code 17681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableListMultimap} 17691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param keyFunction the function used to produce the key for each value 17701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return {@code ImmutableListMultimap} mapping the result of evaluating the 17711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * function {@code keyFunction} on each value in the input collection to 17721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * that value 17731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws NullPointerException if any of the following cases is true: 17741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <ul> 17751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>{@code values} is null 17761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>{@code keyFunction} is null 17771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>An element in {@code values} is null 17781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>{@code keyFunction} returns {@code null} for any element of {@code 17791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values} 17801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * </ul> 17811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 17821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> ImmutableListMultimap<K, V> index( 17831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterable<V> values, Function<? super V, K> keyFunction) { 17841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return index(values.iterator(), keyFunction); 17851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 17881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <b>Deprecated.</b> 17891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 17901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0 17911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @deprecated use {@link #index(Iterator, Function)} by casting {@code 17921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values} to {@code Iterator<V>}, or better yet, by implementing only 17931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code Iterator} and not {@code Iterable}. <b>This method is scheduled 17941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * for deletion in March 2012.</b> 17951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 17961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Beta 17971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Deprecated 17981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V, I extends Object & Iterable<V> & Iterator<V>> 17991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ImmutableListMultimap<K, V> index( 18001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert I values, Function<? super V, K> keyFunction) { 18011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterable<V> valuesIterable = checkNotNull(values); 18021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return index(valuesIterable, keyFunction); 18031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 18061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates an index {@code ImmutableListMultimap} that contains the results of 18071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * applying a specified function to each item in an {@code Iterator} of 18081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values. Each value will be stored as a value in the resulting multimap, 18091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * yielding a multimap with the same size as the input iterator. The key used 18101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * to store that value in the multimap will be the result of calling the 18111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * function on that value. The resulting multimap is created as an immutable 18121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * snapshot. In the returned multimap, keys appear in the order they are first 18131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * encountered, and the values corresponding to each key appear in the same 18141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * order as they are encountered. 18151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 18161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>For example, <pre> {@code 18171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 18181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * List<String> badGuys = 18191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde"); 18201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Function<String, Integer> stringLengthFunction = ...; 18211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimap<Integer, String> index = 18221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimaps.index(badGuys.iterator(), stringLengthFunction); 18231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * System.out.println(index);}</pre> 18241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 18251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * prints <pre> {@code 18261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 18271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {4=[Inky], 6=[Blinky], 5=[Pinky, Pinky, Clyde]}}</pre> 18281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 18291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * The returned multimap is serializable if its keys and values are all 18301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 18311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 18321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param values the values to use when constructing the {@code 18331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableListMultimap} 18341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param keyFunction the function used to produce the key for each value 18351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return {@code ImmutableListMultimap} mapping the result of evaluating the 18361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * function {@code keyFunction} on each value in the input collection to 18371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * that value 18381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws NullPointerException if any of the following cases is true: 18391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <ul> 18401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>{@code values} is null 18411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>{@code keyFunction} is null 18421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>An element in {@code values} is null 18431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>{@code keyFunction} returns {@code null} for any element of {@code 18441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values} 18451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * </ul> 18461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0 18471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 18481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> ImmutableListMultimap<K, V> index( 18491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<V> values, Function<? super V, K> keyFunction) { 18501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(keyFunction); 18511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ImmutableListMultimap.Builder<K, V> builder 18521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = ImmutableListMultimap.builder(); 18531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (values.hasNext()) { 18541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V value = values.next(); 18551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(value, values); 18561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder.put(keyFunction.apply(value), value); 18571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return builder.build(); 18591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static abstract class Keys<K, V> extends AbstractMultiset<K> { 18621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract Multimap<K, V> multimap(); 18631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Iterator<Multiset.Entry<K>> entryIterator() { 18651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<Map.Entry<K, Collection<V>>> backingIterator = 18661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert multimap().asMap().entrySet().iterator(); 18671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Iterator<Multiset.Entry<K>>() { 18681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean hasNext() { 18691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return backingIterator.hasNext(); 18701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Multiset.Entry<K> next() { 18731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map.Entry<K, Collection<V>> backingEntry = 18741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert backingIterator.next(); 18751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Multisets.AbstractEntry<K>() { 18761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public K getElement() { 18771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return backingEntry.getKey(); 18781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int getCount() { 18811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return backingEntry.getValue().size(); 18821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 18841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void remove() { 18871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert backingIterator.remove(); 18881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 18901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override int distinctElements() { 18931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return multimap().asMap().size(); 18941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Set<Multiset.Entry<K>> createEntrySet() { 18971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new KeysEntrySet(); 18981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class KeysEntrySet extends Multisets.EntrySet<K> { 19011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Multiset<K> multiset() { 19021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Keys.this; 19031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<Multiset.Entry<K>> iterator() { 19061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entryIterator(); 19071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 19101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return distinctElements(); 19111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean isEmpty() { 19141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return multimap().isEmpty(); 19151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(@Nullable Object o) { 19181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (o instanceof Multiset.Entry<?>) { 19191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multiset.Entry<?> entry = (Multiset.Entry<?>) o; 19201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> collection = multimap().asMap().get(entry.getElement()); 19211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return collection != null && collection.size() == entry.getCount(); 19221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 19241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(@Nullable Object o) { 19271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (o instanceof Multiset.Entry<?>) { 19281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multiset.Entry<?> entry = (Multiset.Entry<?>) o; 19291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> collection = multimap().asMap().get(entry.getElement()); 19301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (collection != null && collection.size() == entry.getCount()) { 19311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert collection.clear(); 19321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 19331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 19361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(@Nullable Object element) { 19401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return multimap().containsKey(element); 19411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<K> iterator() { 19441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Iterators.transform(multimap().entries().iterator(), 19451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new Function<Map.Entry<K, V>, K>() { 19461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public K apply(Map.Entry<K, V> entry) { 19471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entry.getKey(); 19481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }); 19501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int count(@Nullable Object element) { 19531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 19541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (multimap().containsKey(element)) { 19551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> values = multimap().asMap().get(element); 19561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (values == null) ? 0 : values.size(); 19571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 0; 19591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (ClassCastException e) { 19601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 0; 19611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (NullPointerException e) { 19621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 0; 19631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int remove(@Nullable Object element, int occurrences) { 19671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(occurrences >= 0); 19681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (occurrences == 0) { 19691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return count(element); 19701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> values; 19731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 19741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert values = multimap().asMap().get(element); 19751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (ClassCastException e) { 19761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 0; 19771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (NullPointerException e) { 19781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 0; 19791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (values == null) { 19821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 0; 19831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int oldCount = values.size(); 19861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (occurrences >= oldCount) { 19871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert values.clear(); 19881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 19891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<V> iterator = values.iterator(); 19901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < occurrences; i++) { 19911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.next(); 19921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 19931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return oldCount; 19961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 19991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert multimap().clear(); 20001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<K> elementSet() { 20031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return multimap().keySet(); 20041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static abstract class Values<K, V> extends AbstractCollection<V> { 20081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract Multimap<K, V> multimap(); 20091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<V> iterator() { 20111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<Map.Entry<K, V>> backingIterator = 20121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert multimap().entries().iterator(); 20131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Iterator<V>() { 20141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean hasNext() { 20151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return backingIterator.hasNext(); 20161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V next() { 20191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return backingIterator.next().getValue(); 20201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void remove() { 20231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert backingIterator.remove(); 20241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 20261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 20291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return multimap().size(); 20301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(@Nullable Object o) { 20331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return multimap().containsValue(o); 20341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 20371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert multimap().clear(); 20381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 20421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * A skeleton implementation of {@link Multimap#entries()}. 20431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 20441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static abstract class Entries<K, V> extends 20451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AbstractCollection<Map.Entry<K, V>> { 20461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract Multimap<K, V> multimap(); 20471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 20491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return multimap().size(); 20501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(@Nullable Object o) { 20531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (o instanceof Map.Entry<?, ?>) { 20541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o; 20551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return multimap().containsEntry(entry.getKey(), entry.getValue()); 20561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 20581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(@Nullable Object o) { 20611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (o instanceof Map.Entry<?, ?>) { 20621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o; 20631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return multimap().remove(entry.getKey(), entry.getValue()); 20641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 20661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 20691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert multimap().clear(); 20701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 20741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * A skeleton implementation of {@link SetMultimap#entries()}. 20751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 20761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static abstract class EntrySet<K, V> extends Entries<K, V> implements 20771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Map.Entry<K, V>> { 20781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int hashCode() { 20791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Sets.hashCodeImpl(this); 20801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean equals(@Nullable Object obj) { 20831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Sets.equalsImpl(this, obj); 20841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 20881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * A skeleton implementation of {@link Multimap#asMap()}. 20891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 20901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static abstract class AsMap<K, V> extends 20911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Maps.ImprovedAbstractMap<K, Collection<V>> { 20921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract Multimap<K, V> multimap(); 20931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public abstract int size(); 20951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract Iterator<Entry<K, Collection<V>>> entryIterator(); 20971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Set<Entry<K, Collection<V>>> createEntrySet() { 20991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new EntrySet(); 21001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert void removeValuesForKey(Object key){ 21031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert multimap().removeAll(key); 21041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class EntrySet extends Maps.EntrySet<K, Collection<V>> { 21071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Map<K, Collection<V>> map() { 21081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return AsMap.this; 21091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<Entry<K, Collection<V>>> iterator() { 21121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entryIterator(); 21131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object o) { 21161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!contains(o)) { 21171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 21181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o; 21201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert removeValuesForKey(entry.getKey()); 21211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 21221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 21261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> get(Object key) { 21271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return containsKey(key) ? multimap().get((K) key) : null; 21281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> remove(Object key) { 21311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return containsKey(key) ? multimap().removeAll(key) : null; 21321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<K> keySet() { 21351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return multimap().keySet(); 21361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean isEmpty() { 21391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return multimap().isEmpty(); 21401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsKey(Object key) { 21431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return multimap().containsKey(key); 21441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 21471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert multimap().clear(); 21481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 21521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a multimap containing the mappings in {@code unfiltered} whose keys 21531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * satisfy a predicate. The returned multimap is a live view of 21541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code unfiltered}; changes to one affect the other. 21551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 21561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The resulting multimap's views have iterators that don't support 21571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code remove()}, but all other methods are supported by the multimap and 21581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * its views. When adding a key that doesn't satisfy the predicate, the 21591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap's {@code put()}, {@code putAll()}, and {@replaceValues()} methods 21601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * throw an {@link IllegalArgumentException}. 21611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 21621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When methods such as {@code removeAll()} and {@code clear()} are called on 21631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the filtered multimap or its views, only mappings whose keys satisfy the 21641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * filter will be removed from the underlying multimap. 21651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 21661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap isn't threadsafe or serializable, even if 21671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code unfiltered} is. 21681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 21691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate 21701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * across every key/value mapping in the underlying multimap and determine 21711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * which satisfy the filter. When a live view is <i>not</i> needed, it may be 21721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * faster to copy the filtered multimap and use the copy. 21731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 21741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>, 21751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * as documented at {@link Predicate#apply}. Do not provide a predicate such 21761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent 21771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * with equals. 21781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 21791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 21801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 21811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Beta 21821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible(value = "untested") 21831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> Multimap<K, V> filterKeys( 21841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multimap<K, V> unfiltered, final Predicate<? super K> keyPredicate) { 21851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(keyPredicate); 21861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<Entry<K, V>> entryPredicate = 21871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new Predicate<Entry<K, V>>() { 21881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 21891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean apply(Entry<K, V> input) { 21901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return keyPredicate.apply(input.getKey()); 21911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 21931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return filterEntries(unfiltered, entryPredicate); 21941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 21971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a multimap containing the mappings in {@code unfiltered} whose values 21981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * satisfy a predicate. The returned multimap is a live view of 21991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code unfiltered}; changes to one affect the other. 22001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 22011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The resulting multimap's views have iterators that don't support 22021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code remove()}, but all other methods are supported by the multimap and 22031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * its views. When adding a value that doesn't satisfy the predicate, the 22041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap's {@code put()}, {@code putAll()}, and {@replaceValues()} methods 22051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * throw an {@link IllegalArgumentException}. 22061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 22071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When methods such as {@code removeAll()} and {@code clear()} are called on 22081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the filtered multimap or its views, only mappings whose value satisfy the 22091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * filter will be removed from the underlying multimap. 22101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 22111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap isn't threadsafe or serializable, even if 22121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code unfiltered} is. 22131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 22141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate 22151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * across every key/value mapping in the underlying multimap and determine 22161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * which satisfy the filter. When a live view is <i>not</i> needed, it may be 22171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * faster to copy the filtered multimap and use the copy. 22181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 22191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with 22201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * equals</i>, as documented at {@link Predicate#apply}. Do not provide a 22211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is 22221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * inconsistent with equals. 22231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 22241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 22251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 22261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Beta 22271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible(value = "untested") 22281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> Multimap<K, V> filterValues( 22291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multimap<K, V> unfiltered, final Predicate<? super V> valuePredicate) { 22301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(valuePredicate); 22311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<Entry<K, V>> entryPredicate = 22321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new Predicate<Entry<K, V>>() { 22331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 22341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean apply(Entry<K, V> input) { 22351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return valuePredicate.apply(input.getValue()); 22361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 22381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return filterEntries(unfiltered, entryPredicate); 22391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 22421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a multimap containing the mappings in {@code unfiltered} that 22431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * satisfy a predicate. The returned multimap is a live view of 22441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code unfiltered}; changes to one affect the other. 22451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 22461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The resulting multimap's views have iterators that don't support 22471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code remove()}, but all other methods are supported by the multimap and 22481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * its views. When adding a key/value pair that doesn't satisfy the predicate, 22491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap's {@code put()}, {@code putAll()}, and {@replaceValues()} methods 22501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * throw an {@link IllegalArgumentException}. 22511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 22521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When methods such as {@code removeAll()} and {@code clear()} are called on 22531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the filtered multimap or its views, only mappings whose keys satisfy the 22541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * filter will be removed from the underlying multimap. 22551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 22561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap isn't threadsafe or serializable, even if 22571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code unfiltered} is. 22581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 22591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate 22601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * across every key/value mapping in the underlying multimap and determine 22611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * which satisfy the filter. When a live view is <i>not</i> needed, it may be 22621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * faster to copy the filtered multimap and use the copy. 22631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 22641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with 22651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * equals</i>, as documented at {@link Predicate#apply}. 22661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 22671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 22681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 22691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Beta 22701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible(value = "untested") 22711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> Multimap<K, V> filterEntries( 22721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multimap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) { 22731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(entryPredicate); 22741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (unfiltered instanceof FilteredMultimap) 22751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? filterFiltered((FilteredMultimap<K, V>) unfiltered, entryPredicate) 22761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert : new FilteredMultimap<K, V>(checkNotNull(unfiltered), entryPredicate); 22771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 22801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Support removal operations when filtering a filtered multimap. Since a 22811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * filtered multimap has iterators that don't support remove, passing one to 22821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the FilteredMultimap constructor would lead to a multimap whose removal 22831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * operations would fail. This method combines the predicates to avoid that 22841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * problem. 22851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 22861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <K, V> Multimap<K, V> filterFiltered(FilteredMultimap<K, V> map, 22871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<? super Entry<K, V>> entryPredicate) { 22881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<Entry<K, V>> predicate 22891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = Predicates.and(map.predicate, entryPredicate); 22901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new FilteredMultimap<K, V>(map.unfiltered, predicate); 22911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class FilteredMultimap<K, V> implements Multimap<K, V> { 22941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Multimap<K, V> unfiltered; 22951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Predicate<? super Entry<K, V>> predicate; 22961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert FilteredMultimap(Multimap<K, V> unfiltered, Predicate<? super Entry<K, V>> predicate) { 22981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.unfiltered = unfiltered; 22991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.predicate = predicate; 23001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 23031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entries().size(); 23041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean isEmpty() { 23071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entries().isEmpty(); 23081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsKey(Object key) { 23111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return asMap().containsKey(key); 23121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsValue(Object value) { 23151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return values().contains(value); 23161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // This method should be called only when key is a K and value is a V. 23191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 23201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean satisfiesPredicate(Object key, Object value) { 23211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return predicate.apply(Maps.immutableEntry((K) key, (V) value)); 23221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsEntry(Object key, Object value) { 23251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return unfiltered.containsEntry(key, value) && satisfiesPredicate(key, value); 23261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean put(K key, V value) { 23291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(satisfiesPredicate(key, value)); 23301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return unfiltered.put(key, value); 23311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object key, Object value) { 23341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return containsEntry(key, value) ? unfiltered.remove(key, value) : false; 23351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean putAll(K key, Iterable<? extends V> values) { 23381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (V value : values) { 23391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(satisfiesPredicate(key, value)); 23401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return unfiltered.putAll(key, values); 23421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean putAll(Multimap<? extends K, ? extends V> multimap) { 23451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Entry<? extends K, ? extends V> entry : multimap.entries()) { 23461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(satisfiesPredicate(entry.getKey(), entry.getValue())); 23471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return unfiltered.putAll(multimap); 23491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> replaceValues(K key, Iterable<? extends V> values) { 23521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (V value : values) { 23531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(satisfiesPredicate(key, value)); 23541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Not calling unfiltered.replaceValues() since values that don't satisify 23561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // the filter should remain in the multimap. 23571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> oldValues = removeAll(key); 23581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert unfiltered.putAll(key, values); 23591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return oldValues; 23601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> removeAll(Object key) { 23631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<V> removed = Lists.newArrayList(); 23641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> values = unfiltered.asMap().get(key); 23651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (values != null) { 23661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<V> iterator = values.iterator(); 23671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (iterator.hasNext()) { 23681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V value = iterator.next(); 23691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (satisfiesPredicate(key, value)) { 23701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert removed.add(value); 23711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 23721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (unfiltered instanceof SetMultimap) { 23761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Collections.unmodifiableSet(Sets.newLinkedHashSet(removed)); 23771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 23781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Collections.unmodifiableList(removed); 23791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 23831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entries().clear(); 23841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean equals(@Nullable Object object) { 23871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (object == this) { 23881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 23891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (object instanceof Multimap) { 23911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multimap<?, ?> that = (Multimap<?, ?>) object; 23921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return asMap().equals(that.asMap()); 23931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 23951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int hashCode() { 23981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return asMap().hashCode(); 23991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public String toString() { 24021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return asMap().toString(); 24031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class ValuePredicate implements Predicate<V> { 24061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final K key; 24071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ValuePredicate(K key) { 24081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.key = key; 24091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean apply(V value) { 24111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return satisfiesPredicate(key, value); 24121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> filterCollection(Collection<V> collection, Predicate<V> predicate) { 24161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (collection instanceof Set) { 24171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Sets.filter((Set<V>) collection, predicate); 24181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 24191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Collections2.filter(collection, predicate); 24201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> get(K key) { 24241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return filterCollection(unfiltered.get(key), new ValuePredicate(key)); 24251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<K> keySet() { 24281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return asMap().keySet(); 24291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> values; 24321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> values() { 24341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (values == null) ? values = new Values() : values; 24351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class Values extends Multimaps.Values<K, V> { 24381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Multimap<K, V> multimap() { 24391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return FilteredMultimap.this; 24401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(@Nullable Object o) { 24431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Iterators.contains(iterator(), o); 24441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Override remove methods since iterator doesn't support remove. 24471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object o) { 24491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<Entry<K, V>> iterator = unfiltered.entries().iterator(); 24501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (iterator.hasNext()) { 24511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<K, V> entry = iterator.next(); 24521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (Objects.equal(o, entry.getValue()) && predicate.apply(entry)) { 24531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 24541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 24551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 24581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean removeAll(Collection<?> c) { 24611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = false; 24621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<Entry<K, V>> iterator = unfiltered.entries().iterator(); 24631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (iterator.hasNext()) { 24641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<K, V> entry = iterator.next(); 24651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (c.contains(entry.getValue()) && predicate.apply(entry)) { 24661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 24671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed = true; 24681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changed; 24711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean retainAll(Collection<?> c) { 24741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = false; 24751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<Entry<K, V>> iterator = unfiltered.entries().iterator(); 24761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (iterator.hasNext()) { 24771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<K, V> entry = iterator.next(); 24781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!c.contains(entry.getValue()) && predicate.apply(entry)) { 24791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 24801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed = true; 24811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changed; 24841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<Entry<K, V>> entries; 24881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<Entry<K, V>> entries() { 24901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (entries == null) 24911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? entries = Collections2.filter(unfiltered.entries(), predicate) 24921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert : entries; 24931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 24961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Remove all filtered asMap() entries that satisfy the predicate. 24971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 24981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean removeEntriesIf(Predicate<Map.Entry<K, Collection<V>>> removalPredicate) { 24991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<Map.Entry<K, Collection<V>>> iterator = unfiltered.asMap().entrySet().iterator(); 25001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = false; 25011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (iterator.hasNext()) { 25021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Determine whether to remove the filtered values with this key. 25031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map.Entry<K, Collection<V>> entry = iterator.next(); 25041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K key = entry.getKey(); 25051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> collection = entry.getValue(); 25061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<V> valuePredicate = new ValuePredicate(key); 25071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> filteredCollection = filterCollection(collection, valuePredicate); 25081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map.Entry<K, Collection<V>> filteredEntry = Maps.immutableEntry(key, filteredCollection); 25091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (removalPredicate.apply(filteredEntry) && !filteredCollection.isEmpty()) { 25101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed = true; 25111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (Iterables.all(collection, valuePredicate)) { 25121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); // Remove all values for the key. 25131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 25141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert filteredCollection.clear(); // Remove the filtered values only. 25151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changed; 25191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, Collection<V>> asMap; 25221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Map<K, Collection<V>> asMap() { 25241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (asMap == null) ? asMap = createAsMap() : asMap; 25251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static final Predicate<Collection<?>> NOT_EMPTY = new Predicate<Collection<?>>() { 25281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean apply(Collection<?> input) { 25291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return !input.isEmpty(); 25301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 25321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, Collection<V>> createAsMap() { 25341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Select the values that satisify the predicate. 25351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryTransformer<K, Collection<V>, Collection<V>> transformer 25361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = new EntryTransformer<K, Collection<V>, Collection<V>>() { 25371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> transformEntry(K key, Collection<V> collection) { 25381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return filterCollection(collection, new ValuePredicate(key)); 25391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 25411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, Collection<V>> transformed 25421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = Maps.transformEntries(unfiltered.asMap(), transformer); 25431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Select the keys that have at least one value remaining. 25451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, Collection<V>> filtered = Maps.filterValues(transformed, NOT_EMPTY); 25461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Override the removal methods, since removing a map entry should not 25481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // affect values that don't satisfy the filter. 25491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new AsMap(filtered); 25501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class AsMap extends ForwardingMap<K, Collection<V>> { 25531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map<K, Collection<V>> delegate; 25541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AsMap(Map<K, Collection<V>> delegate) { 25561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.delegate = delegate; 25571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Map<K, Collection<V>> delegate() { 25601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate; 25611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> remove(Object o) { 25641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> output = FilteredMultimap.this.removeAll(o); 25651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return output.isEmpty() ? null : output; 25661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 25691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert FilteredMultimap.this.clear(); 25701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<K> keySet; 25731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<K> keySet() { 25751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (keySet == null) ? keySet = new KeySet() : keySet; 25761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class KeySet extends Maps.KeySet<K, Collection<V>> { 25791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Map<K, Collection<V>> map() { 25801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return AsMap.this; 25811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object o) { 25841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> collection = delegate.get(o); 25851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (collection == null) { 25861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 25871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert collection.clear(); 25891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 25901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean removeAll(Collection<?> c) { 25931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Sets.removeAllImpl(this, c); 25941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean retainAll(final Collection<?> c) { 25971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<Map.Entry<K, Collection<V>>> removalPredicate 25981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = new Predicate<Map.Entry<K, Collection<V>>>() { 25991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean apply(Map.Entry<K, Collection<V>> entry) { 26001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return !c.contains(entry.getKey()); 26011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 26031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return removeEntriesIf(removalPredicate); 26041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Values asMapValues; 26081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<Collection<V>> values() { 26101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (asMapValues == null) ? asMapValues = new Values() : asMapValues; 26111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class Values extends Maps.Values<K, Collection<V>> { 26141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Map<K, Collection<V>> map() { 26151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return AsMap.this; 26161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object o) { 26191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Collection<V> collection : this) { 26201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (collection.equals(o)) { 26211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert collection.clear(); 26221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 26231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 26261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean removeAll(final Collection<?> c) { 26291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<Map.Entry<K, Collection<V>>> removalPredicate 26301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = new Predicate<Map.Entry<K, Collection<V>>>() { 26311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean apply(Map.Entry<K, Collection<V>> entry) { 26321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return c.contains(entry.getValue()); 26331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 26351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return removeEntriesIf(removalPredicate); 26361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean retainAll(final Collection<?> c) { 26391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<Map.Entry<K, Collection<V>>> removalPredicate 26401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = new Predicate<Map.Entry<K, Collection<V>>>() { 26411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean apply(Map.Entry<K, Collection<V>> entry) { 26421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return !c.contains(entry.getValue()); 26431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 26451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return removeEntriesIf(removalPredicate); 26461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntrySet entrySet; 26501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<Map.Entry<K, Collection<V>>> entrySet() { 26521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (entrySet == null) ? entrySet = new EntrySet(super.entrySet()) : entrySet; 26531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class EntrySet extends Maps.EntrySet<K, Collection<V>> { 26561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Map.Entry<K, Collection<V>>> delegateEntries; 26571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public EntrySet(Set<Map.Entry<K, Collection<V>>> delegateEntries) { 26591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.delegateEntries = delegateEntries; 26601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Map<K, Collection<V>> map() { 26631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return AsMap.this; 26641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<Map.Entry<K, Collection<V>>> iterator() { 26671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegateEntries.iterator(); 26681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object o) { 26711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (o instanceof Entry<?, ?>) { 26721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<?, ?> entry = (Entry<?, ?>) o; 26731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> collection = delegate.get(entry.getKey()); 26741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (collection != null && collection.equals(entry.getValue())) { 26751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert collection.clear(); 26761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 26771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 26801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean removeAll(Collection<?> c) { 26831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Sets.removeAllImpl(this, c); 26841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean retainAll(final Collection<?> c) { 26871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<Map.Entry<K, Collection<V>>> removalPredicate 26881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = new Predicate<Map.Entry<K, Collection<V>>>() { 26891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean apply(Map.Entry<K, Collection<V>> entry) { 26901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return !c.contains(entry); 26911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 26931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return removeEntriesIf(removalPredicate); 26941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AbstractMultiset<K> keys; 26991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Multiset<K> keys() { 27011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (keys == null) ? keys = new Keys() : keys; 27021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class Keys extends Multimaps.Keys<K, V> { 27051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Multimap<K, V> multimap() { 27061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return FilteredMultimap.this; 27071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int remove(Object o, int occurrences) { 27101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(occurrences >= 0); 27111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> values = unfiltered.asMap().get(o); 27121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (values == null) { 27131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 0; 27141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int priorCount = 0; 27161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int removed = 0; 27171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<V> iterator = values.iterator(); 27181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (iterator.hasNext()) { 27191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (satisfiesPredicate(o, iterator.next())) { 27201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert priorCount++; 27211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (removed < occurrences) { 27221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 27231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert removed++; 27241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return priorCount; 27281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Set<Multiset.Entry<K>> createEntrySet() { 27311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new EntrySet(); 27321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class EntrySet extends Multimaps.Keys<K, V>.KeysEntrySet { 27351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean removeAll(Collection<?> c) { 27361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Sets.removeAllImpl(this, c); 27371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean retainAll(final Collection<?> c) { 27401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<Map.Entry<K, Collection<V>>> removalPredicate 27411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = new Predicate<Map.Entry<K, Collection<V>>>() { 27421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean apply(Map.Entry<K, Collection<V>> entry) { 27431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multiset.Entry<K> multisetEntry 27441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = Multisets.immutableEntry(entry.getKey(), entry.getValue().size()); 27451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return !c.contains(multisetEntry); 27461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 27481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return removeEntriesIf(removalPredicate); 27491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // TODO(jlevy): Create methods that filter a SetMultimap or SortedSetMultimap. 27551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 2756