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