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.checkNotNull; 200888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport static com.google.common.collect.CollectPreconditions.checkNonnegative; 210888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport static com.google.common.collect.CollectPreconditions.checkRemove; 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 230888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.annotations.Beta; 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible; 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtIncompatible; 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Function; 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Predicate; 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Predicates; 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Supplier; 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Maps.EntryTransformer; 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.IOException; 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.ObjectInputStream; 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.ObjectOutputStream; 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.Serializable; 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.AbstractCollection; 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collection; 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collections; 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Comparator; 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.HashSet; 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Iterator; 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.List; 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map; 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map.Entry; 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.NoSuchElementException; 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Set; 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.SortedSet; 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport javax.annotation.Nullable; 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Provides static methods acting on or generating a {@code Multimap}. 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 547dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>See the Guava User Guide article on <a href= 557dd252788645e940eada959bdde927426e2531c9Paul Duffin * "http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Multimaps"> 567dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@code Multimaps}</a>. 577dd252788645e940eada959bdde927426e2531c9Paul Duffin * 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Jared Levy 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Robert Konigsberg 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Mike Bostock 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Louis Wasserman 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 2.0 (imported from Google Collections Library) 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible(emulated = true) 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic final class Multimaps { 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private Multimaps() {} 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 697dd252788645e940eada959bdde927426e2531c9Paul Duffin * Creates a new {@code Multimap} backed by {@code map}, whose internal value 707dd252788645e940eada959bdde927426e2531c9Paul Duffin * collections are generated by {@code factory}. 717dd252788645e940eada959bdde927426e2531c9Paul Duffin * 727dd252788645e940eada959bdde927426e2531c9Paul Duffin * <b>Warning: do not use</b> this method when the collections returned by 737dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@code factory} implement either {@link List} or {@code Set}! Use the more 747dd252788645e940eada959bdde927426e2531c9Paul Duffin * specific method {@link #newListMultimap}, {@link #newSetMultimap} or {@link 757dd252788645e940eada959bdde927426e2531c9Paul Duffin * #newSortedSetMultimap} instead, to avoid very surprising behavior from 767dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@link Multimap#equals}. 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The {@code factory}-generated and {@code map} classes determine the 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap iteration order. They also specify the behavior of the 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code equals}, {@code hashCode}, and {@code toString} methods for the 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap and its returned views. However, the multimap's {@code get} 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * method returns instances of a different class than {@code factory.get()} 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * does. 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The multimap is serializable if {@code map}, {@code factory}, the 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * collections generated by {@code factory}, and the multimap contents are all 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The multimap is not threadsafe when any concurrent operations update the 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap, even if {@code map} and the instances generated by 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code factory} are. Concurrent read operations will work correctly. To 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * allow concurrent update operations, wrap the multimap with a call to 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link #synchronizedMultimap}. 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Call this method only when the simpler methods 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link ArrayListMultimap#create()}, {@link HashMultimap#create()}, 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link LinkedHashMultimap#create()}, {@link LinkedListMultimap#create()}, 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link TreeMultimap#create()}, and 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice. 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note: the multimap assumes complete ownership over of {@code map} and 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the collections returned by {@code factory}. Those objects should not be 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * manually updated and they should not use soft, weak, or phantom references. 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param map place to store the mapping from each key to its corresponding 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param factory supplier of new, empty collections that will each hold all 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values for a given key 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code map} is not empty 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> Multimap<K, V> newMultimap(Map<K, Collection<V>> map, 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Supplier<? extends Collection<V>> factory) { 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new CustomMultimap<K, V>(map, factory); 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1167dd252788645e940eada959bdde927426e2531c9Paul Duffin private static class CustomMultimap<K, V> extends AbstractMapBasedMultimap<K, V> { 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Supplier<? extends Collection<V>> factory; 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1190888a09821a98ac0680fad765217302858e70fa4Paul Duffin CustomMultimap(Map<K, Collection<V>> map, 1200888a09821a98ac0680fad765217302858e70fa4Paul Duffin Supplier<? extends Collection<V>> factory) { 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(map); 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.factory = checkNotNull(factory); 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1250888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override protected Collection<V> createCollection() { 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return factory.get(); 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // can't use Serialization writeMultimap and populateMultimap methods since 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // there's no way to generate the empty backing map. 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @serialData the factory and the backing map */ 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java.io.ObjectOutputStream") 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void writeObject(ObjectOutputStream stream) throws IOException { 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.defaultWriteObject(); 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.writeObject(factory); 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.writeObject(backingMap()); 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java.io.ObjectInputStream") 1410888a09821a98ac0680fad765217302858e70fa4Paul Duffin @SuppressWarnings("unchecked") // reading data stored by writeObject 1420888a09821a98ac0680fad765217302858e70fa4Paul Duffin private void readObject(ObjectInputStream stream) 1430888a09821a98ac0680fad765217302858e70fa4Paul Duffin throws IOException, ClassNotFoundException { 1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.defaultReadObject(); 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert factory = (Supplier<? extends Collection<V>>) stream.readObject(); 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject(); 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert setMap(map); 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java serialization not supported") 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a new {@code ListMultimap} that uses the provided map and factory. 1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * It can generate a multimap based on arbitrary {@link Map} and {@link List} 1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * classes. 1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The {@code factory}-generated and {@code map} classes determine the 1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap iteration order. They also specify the behavior of the 1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code equals}, {@code hashCode}, and {@code toString} methods for the 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap and its returned views. The multimap's {@code get}, {@code 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * removeAll}, and {@code replaceValues} methods return {@code RandomAccess} 1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * lists if the factory does. However, the multimap's {@code get} method 1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returns instances of a different class than does {@code factory.get()}. 1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The multimap is serializable if {@code map}, {@code factory}, the 1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * lists generated by {@code factory}, and the multimap contents are all 1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The multimap is not threadsafe when any concurrent operations update the 1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap, even if {@code map} and the instances generated by 1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code factory} are. Concurrent read operations will work correctly. To 1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * allow concurrent update operations, wrap the multimap with a call to 1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link #synchronizedListMultimap}. 1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Call this method only when the simpler methods 1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link ArrayListMultimap#create()} and {@link LinkedListMultimap#create()} 1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * won't suffice. 1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note: the multimap assumes complete ownership over of {@code map} and 1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the lists returned by {@code factory}. Those objects should not be manually 1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * updated, they should be empty when provided, and they should not use soft, 1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * weak, or phantom references. 1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param map place to store the mapping from each key to its corresponding 1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values 1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param factory supplier of new, empty lists that will each hold all values 1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * for a given key 1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code map} is not empty 1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1920888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> ListMultimap<K, V> newListMultimap( 1930888a09821a98ac0680fad765217302858e70fa4Paul Duffin Map<K, Collection<V>> map, final Supplier<? extends List<V>> factory) { 1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new CustomListMultimap<K, V>(map, factory); 1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1970888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static class CustomListMultimap<K, V> 1980888a09821a98ac0680fad765217302858e70fa4Paul Duffin extends AbstractListMultimap<K, V> { 1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Supplier<? extends List<V>> factory; 2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2010888a09821a98ac0680fad765217302858e70fa4Paul Duffin CustomListMultimap(Map<K, Collection<V>> map, 2020888a09821a98ac0680fad765217302858e70fa4Paul Duffin Supplier<? extends List<V>> factory) { 2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(map); 2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.factory = checkNotNull(factory); 2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2070888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override protected List<V> createCollection() { 2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return factory.get(); 2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @serialData the factory and the backing map */ 2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java.io.ObjectOutputStream") 2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void writeObject(ObjectOutputStream stream) throws IOException { 2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.defaultWriteObject(); 2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.writeObject(factory); 2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.writeObject(backingMap()); 2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java.io.ObjectInputStream") 2200888a09821a98ac0680fad765217302858e70fa4Paul Duffin @SuppressWarnings("unchecked") // reading data stored by writeObject 2210888a09821a98ac0680fad765217302858e70fa4Paul Duffin private void readObject(ObjectInputStream stream) 2220888a09821a98ac0680fad765217302858e70fa4Paul Duffin throws IOException, ClassNotFoundException { 2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.defaultReadObject(); 2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert factory = (Supplier<? extends List<V>>) stream.readObject(); 2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject(); 2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert setMap(map); 2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java serialization not supported") 2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a new {@code SetMultimap} that uses the provided map and factory. 2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * It can generate a multimap based on arbitrary {@link Map} and {@link Set} 2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * classes. 2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The {@code factory}-generated and {@code map} classes determine the 2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap iteration order. They also specify the behavior of the 2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code equals}, {@code hashCode}, and {@code toString} methods for the 2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap and its returned views. However, the multimap's {@code get} 2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * method returns instances of a different class than {@code factory.get()} 2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * does. 2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The multimap is serializable if {@code map}, {@code factory}, the 2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * sets generated by {@code factory}, and the multimap contents are all 2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The multimap is not threadsafe when any concurrent operations update the 2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap, even if {@code map} and the instances generated by 2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code factory} are. Concurrent read operations will work correctly. To 2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * allow concurrent update operations, wrap the multimap with a call to 2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link #synchronizedSetMultimap}. 2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Call this method only when the simpler methods 2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link HashMultimap#create()}, {@link LinkedHashMultimap#create()}, 2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link TreeMultimap#create()}, and 2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice. 2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note: the multimap assumes complete ownership over of {@code map} and 2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the sets returned by {@code factory}. Those objects should not be manually 2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * updated and they should not use soft, weak, or phantom references. 2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param map place to store the mapping from each key to its corresponding 2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values 2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param factory supplier of new, empty sets that will each hold all values 2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * for a given key 2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code map} is not empty 2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2700888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> SetMultimap<K, V> newSetMultimap( 2710888a09821a98ac0680fad765217302858e70fa4Paul Duffin Map<K, Collection<V>> map, final Supplier<? extends Set<V>> factory) { 2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new CustomSetMultimap<K, V>(map, factory); 2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2750888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static class CustomSetMultimap<K, V> 2760888a09821a98ac0680fad765217302858e70fa4Paul Duffin extends AbstractSetMultimap<K, V> { 2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Supplier<? extends Set<V>> factory; 2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2790888a09821a98ac0680fad765217302858e70fa4Paul Duffin CustomSetMultimap(Map<K, Collection<V>> map, 2800888a09821a98ac0680fad765217302858e70fa4Paul Duffin Supplier<? extends Set<V>> factory) { 2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(map); 2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.factory = checkNotNull(factory); 2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2850888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override protected Set<V> createCollection() { 2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return factory.get(); 2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @serialData the factory and the backing map */ 2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java.io.ObjectOutputStream") 2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void writeObject(ObjectOutputStream stream) throws IOException { 2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.defaultWriteObject(); 2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.writeObject(factory); 2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.writeObject(backingMap()); 2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java.io.ObjectInputStream") 2980888a09821a98ac0680fad765217302858e70fa4Paul Duffin @SuppressWarnings("unchecked") // reading data stored by writeObject 2990888a09821a98ac0680fad765217302858e70fa4Paul Duffin private void readObject(ObjectInputStream stream) 3000888a09821a98ac0680fad765217302858e70fa4Paul Duffin throws IOException, ClassNotFoundException { 3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.defaultReadObject(); 3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert factory = (Supplier<? extends Set<V>>) stream.readObject(); 3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject(); 3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert setMap(map); 3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("not needed in emulated source") 3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates a new {@code SortedSetMultimap} that uses the provided map and 3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * factory. It can generate a multimap based on arbitrary {@link Map} and 3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link SortedSet} classes. 3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The {@code factory}-generated and {@code map} classes determine the 3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap iteration order. They also specify the behavior of the 3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code equals}, {@code hashCode}, and {@code toString} methods for the 3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap and its returned views. However, the multimap's {@code get} 3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * method returns instances of a different class than {@code factory.get()} 3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * does. 3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The multimap is serializable if {@code map}, {@code factory}, the 3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * sets generated by {@code factory}, and the multimap contents are all 3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The multimap is not threadsafe when any concurrent operations update the 3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap, even if {@code map} and the instances generated by 3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code factory} are. Concurrent read operations will work correctly. To 3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * allow concurrent update operations, wrap the multimap with a call to 3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link #synchronizedSortedSetMultimap}. 3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Call this method only when the simpler methods 3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link TreeMultimap#create()} and 3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice. 3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note: the multimap assumes complete ownership over of {@code map} and 3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the sets returned by {@code factory}. Those objects should not be manually 3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * updated and they should not use soft, weak, or phantom references. 3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param map place to store the mapping from each key to its corresponding 3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values 3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param factory supplier of new, empty sorted sets that will each hold 3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * all values for a given key 3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code map} is not empty 3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3470888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> SortedSetMultimap<K, V> newSortedSetMultimap( 3480888a09821a98ac0680fad765217302858e70fa4Paul Duffin Map<K, Collection<V>> map, 3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Supplier<? extends SortedSet<V>> factory) { 3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new CustomSortedSetMultimap<K, V>(map, factory); 3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3530888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static class CustomSortedSetMultimap<K, V> 3540888a09821a98ac0680fad765217302858e70fa4Paul Duffin extends AbstractSortedSetMultimap<K, V> { 3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Supplier<? extends SortedSet<V>> factory; 3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Comparator<? super V> valueComparator; 3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3580888a09821a98ac0680fad765217302858e70fa4Paul Duffin CustomSortedSetMultimap(Map<K, Collection<V>> map, 3590888a09821a98ac0680fad765217302858e70fa4Paul Duffin Supplier<? extends SortedSet<V>> factory) { 3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(map); 3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.factory = checkNotNull(factory); 3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert valueComparator = factory.get().comparator(); 3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3650888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override protected SortedSet<V> createCollection() { 3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return factory.get(); 3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3690888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Comparator<? super V> valueComparator() { 3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return valueComparator; 3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @serialData the factory and the backing map */ 3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java.io.ObjectOutputStream") 3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void writeObject(ObjectOutputStream stream) throws IOException { 3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.defaultWriteObject(); 3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.writeObject(factory); 3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.writeObject(backingMap()); 3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java.io.ObjectInputStream") 3820888a09821a98ac0680fad765217302858e70fa4Paul Duffin @SuppressWarnings("unchecked") // reading data stored by writeObject 3830888a09821a98ac0680fad765217302858e70fa4Paul Duffin private void readObject(ObjectInputStream stream) 3840888a09821a98ac0680fad765217302858e70fa4Paul Duffin throws IOException, ClassNotFoundException { 3851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert stream.defaultReadObject(); 3861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert factory = (Supplier<? extends SortedSet<V>>) stream.readObject(); 3871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert valueComparator = factory.get().comparator(); 3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject(); 3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert setMap(map); 3901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("not needed in emulated source") 3931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 3941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copies each key-value mapping in {@code source} into {@code dest}, with 3981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * its key and value reversed. 3991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>If {@code source} is an {@link ImmutableMultimap}, consider using 4011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link ImmutableMultimap#inverse} instead. 4021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param source any multimap 4041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param dest the multimap to copy into; usually empty 4051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return {@code dest} 4061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 4071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V, M extends Multimap<K, V>> M invertFrom( 4081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multimap<? extends V, ? extends K> source, M dest) { 4091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(dest); 4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Map.Entry<? extends V, ? extends K> entry : source.entries()) { 4111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert dest.put(entry.getValue(), entry.getKey()); 4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return dest; 4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 4171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a synchronized (thread-safe) multimap backed by the specified 4181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap. In order to guarantee serial access, it is critical that 4191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <b>all</b> access to the backing multimap is accomplished through the 4201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned multimap. 4211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>It is imperative that the user manually synchronize on the returned 4231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap when accessing any of its collection views: <pre> {@code 4241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4257dd252788645e940eada959bdde927426e2531c9Paul Duffin * Multimap<K, V> multimap = Multimaps.synchronizedMultimap( 4261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * HashMultimap.<K, V>create()); 4271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ... 4287dd252788645e940eada959bdde927426e2531c9Paul Duffin * Collection<V> values = multimap.get(key); // Needn't be in synchronized block 4291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ... 4307dd252788645e940eada959bdde927426e2531c9Paul Duffin * synchronized (multimap) { // Synchronizing on multimap, not values! 4317dd252788645e940eada959bdde927426e2531c9Paul Duffin * Iterator<V> i = values.iterator(); // Must be in synchronized block 4321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * while (i.hasNext()) { 4331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * foo(i.next()); 4341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * } 4351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * }}</pre> 4361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4370888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>Failure to follow this advice may result in non-deterministic behavior. 4381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that the generated multimap's {@link Multimap#removeAll} and 4401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Multimap#replaceValues} methods return collections that aren't 4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * synchronized. 4421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap will be serializable if the specified multimap is 4441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 4451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param multimap the multimap to be wrapped in a synchronized view 4471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a synchronized view of the specified multimap 4481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 4490888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> Multimap<K, V> synchronizedMultimap( 4500888a09821a98ac0680fad765217302858e70fa4Paul Duffin Multimap<K, V> multimap) { 4511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Synchronized.multimap(multimap, null); 4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 4551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an unmodifiable view of the specified multimap. Query operations on 4561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the returned multimap "read through" to the specified multimap, and 4571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * attempts to modify the returned multimap, either directly or through the 4581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap's views, result in an {@code UnsupportedOperationException}. 4591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that the generated multimap's {@link Multimap#removeAll} and 4611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Multimap#replaceValues} methods return collections that are 4621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * modifiable. 4631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap will be serializable if the specified multimap is 4651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 4661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param delegate the multimap for which an unmodifiable view is to be 4681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned 4691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return an unmodifiable view of the specified multimap 4701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 4710888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> Multimap<K, V> unmodifiableMultimap( 4720888a09821a98ac0680fad765217302858e70fa4Paul Duffin Multimap<K, V> delegate) { 4730888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (delegate instanceof UnmodifiableMultimap || 4740888a09821a98ac0680fad765217302858e70fa4Paul Duffin delegate instanceof ImmutableMultimap) { 4751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate; 4761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new UnmodifiableMultimap<K, V>(delegate); 4781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 4811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Simply returns its argument. 4821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @deprecated no need to use this 4841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0 4851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 4860888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Deprecated public static <K, V> Multimap<K, V> unmodifiableMultimap( 4870888a09821a98ac0680fad765217302858e70fa4Paul Duffin ImmutableMultimap<K, V> delegate) { 4881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return checkNotNull(delegate); 4891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4910888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static class UnmodifiableMultimap<K, V> 4920888a09821a98ac0680fad765217302858e70fa4Paul Duffin extends ForwardingMultimap<K, V> implements Serializable { 4931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Multimap<K, V> delegate; 4941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Collection<Entry<K, V>> entries; 4951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Multiset<K> keys; 4961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Set<K> keySet; 4971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Collection<V> values; 4981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Map<K, Collection<V>> map; 4991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert UnmodifiableMultimap(final Multimap<K, V> delegate) { 5011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.delegate = checkNotNull(delegate); 5021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5040888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override protected Multimap<K, V> delegate() { 5051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate; 5061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5080888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public void clear() { 5091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 5101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5120888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Map<K, Collection<V>> asMap() { 5131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, Collection<V>> result = map; 5141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 5150888a09821a98ac0680fad765217302858e70fa4Paul Duffin result = map = Collections.unmodifiableMap( 5160888a09821a98ac0680fad765217302858e70fa4Paul Duffin Maps.transformValues(delegate.asMap(), new Function<Collection<V>, Collection<V>>() { 5170888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 5180888a09821a98ac0680fad765217302858e70fa4Paul Duffin public Collection<V> apply(Collection<V> collection) { 5190888a09821a98ac0680fad765217302858e70fa4Paul Duffin return unmodifiableValueCollection(collection); 5200888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 5210888a09821a98ac0680fad765217302858e70fa4Paul Duffin })); 5221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 5241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5260888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Collection<Entry<K, V>> entries() { 5271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<Entry<K, V>> result = entries; 5281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 5291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entries = result = unmodifiableEntries(delegate.entries()); 5301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 5321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5340888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Collection<V> get(K key) { 5351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return unmodifiableValueCollection(delegate.get(key)); 5361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5380888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Multiset<K> keys() { 5391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multiset<K> result = keys; 5401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 5411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert keys = result = Multisets.unmodifiableMultiset(delegate.keys()); 5421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 5441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5460888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Set<K> keySet() { 5471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<K> result = keySet; 5481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 5491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert keySet = result = Collections.unmodifiableSet(delegate.keySet()); 5501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 5521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5540888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean put(K key, V value) { 5551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 5561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5580888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean putAll(K key, Iterable<? extends V> values) { 5591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 5601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 5631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean putAll(Multimap<? extends K, ? extends V> multimap) { 5641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 5651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5670888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean remove(Object key, Object value) { 5681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 5691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5710888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Collection<V> removeAll(Object key) { 5721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 5731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5750888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Collection<V> replaceValues( 5760888a09821a98ac0680fad765217302858e70fa4Paul Duffin K key, Iterable<? extends V> values) { 5771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 5781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5800888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Collection<V> values() { 5811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> result = values; 5821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 5831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert values = result = Collections.unmodifiableCollection(delegate.values()); 5841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 5861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 5891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5910888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static class UnmodifiableListMultimap<K, V> 5920888a09821a98ac0680fad765217302858e70fa4Paul Duffin extends UnmodifiableMultimap<K, V> implements ListMultimap<K, V> { 5931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert UnmodifiableListMultimap(ListMultimap<K, V> delegate) { 5941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(delegate); 5951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5960888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public ListMultimap<K, V> delegate() { 5971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (ListMultimap<K, V>) super.delegate(); 5981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5990888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public List<V> get(K key) { 6001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Collections.unmodifiableList(delegate().get(key)); 6011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6020888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public List<V> removeAll(Object key) { 6031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 6041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6050888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public List<V> replaceValues( 6060888a09821a98ac0680fad765217302858e70fa4Paul Duffin K key, Iterable<? extends V> values) { 6071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 6081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 6101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6120888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static class UnmodifiableSetMultimap<K, V> 6130888a09821a98ac0680fad765217302858e70fa4Paul Duffin extends UnmodifiableMultimap<K, V> implements SetMultimap<K, V> { 6141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert UnmodifiableSetMultimap(SetMultimap<K, V> delegate) { 6151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(delegate); 6161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6170888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public SetMultimap<K, V> delegate() { 6181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (SetMultimap<K, V>) super.delegate(); 6191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6200888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Set<V> get(K key) { 6211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /* 6221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Note that this doesn't return a SortedSet when delegate is a 6231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * SortedSetMultiset, unlike (SortedSet<V>) super.get(). 6241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 6251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Collections.unmodifiableSet(delegate().get(key)); 6261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6270888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Set<Map.Entry<K, V>> entries() { 6281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Maps.unmodifiableEntrySet(delegate().entries()); 6291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6300888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Set<V> removeAll(Object key) { 6311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 6321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6330888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Set<V> replaceValues( 6340888a09821a98ac0680fad765217302858e70fa4Paul Duffin K key, Iterable<? extends V> values) { 6351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 6361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 6381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6400888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static class UnmodifiableSortedSetMultimap<K, V> 6410888a09821a98ac0680fad765217302858e70fa4Paul Duffin extends UnmodifiableSetMultimap<K, V> implements SortedSetMultimap<K, V> { 6421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert UnmodifiableSortedSetMultimap(SortedSetMultimap<K, V> delegate) { 6431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(delegate); 6441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6450888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public SortedSetMultimap<K, V> delegate() { 6461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (SortedSetMultimap<K, V>) super.delegate(); 6471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6480888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public SortedSet<V> get(K key) { 6491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Collections.unmodifiableSortedSet(delegate().get(key)); 6501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6510888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public SortedSet<V> removeAll(Object key) { 6521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 6531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6540888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public SortedSet<V> replaceValues( 6550888a09821a98ac0680fad765217302858e70fa4Paul Duffin K key, Iterable<? extends V> values) { 6561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 6571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6580888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 6591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Comparator<? super V> valueComparator() { 6601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate().valueComparator(); 6611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 6631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 6661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a synchronized (thread-safe) {@code SetMultimap} backed by the 6671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * specified multimap. 6681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>You must follow the warnings described in {@link #synchronizedMultimap}. 6701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap will be serializable if the specified multimap is 6721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 6731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param multimap the multimap to be wrapped 6751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a synchronized view of the specified multimap 6761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 6770888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> SetMultimap<K, V> synchronizedSetMultimap( 6780888a09821a98ac0680fad765217302858e70fa4Paul Duffin SetMultimap<K, V> multimap) { 6791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Synchronized.setMultimap(multimap, null); 6801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 6831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an unmodifiable view of the specified {@code SetMultimap}. Query 6841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * operations on the returned multimap "read through" to the specified 6851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap, and attempts to modify the returned multimap, either directly or 6861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * through the multimap's views, result in an 6871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code UnsupportedOperationException}. 6881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that the generated multimap's {@link Multimap#removeAll} and 6901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Multimap#replaceValues} methods return collections that are 6911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * modifiable. 6921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap will be serializable if the specified multimap is 6941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 6951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param delegate the multimap for which an unmodifiable view is to be 6971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned 6981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return an unmodifiable view of the specified multimap 6991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 7000888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> SetMultimap<K, V> unmodifiableSetMultimap( 7010888a09821a98ac0680fad765217302858e70fa4Paul Duffin SetMultimap<K, V> delegate) { 7020888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (delegate instanceof UnmodifiableSetMultimap || 7030888a09821a98ac0680fad765217302858e70fa4Paul Duffin delegate instanceof ImmutableSetMultimap) { 7041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate; 7051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new UnmodifiableSetMultimap<K, V>(delegate); 7071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 7101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Simply returns its argument. 7111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @deprecated no need to use this 7131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0 7141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 7150888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Deprecated public static <K, V> SetMultimap<K, V> unmodifiableSetMultimap( 7160888a09821a98ac0680fad765217302858e70fa4Paul Duffin ImmutableSetMultimap<K, V> delegate) { 7171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return checkNotNull(delegate); 7181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 7211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a synchronized (thread-safe) {@code SortedSetMultimap} backed by 7221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the specified multimap. 7231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>You must follow the warnings described in {@link #synchronizedMultimap}. 7251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap will be serializable if the specified multimap is 7271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 7281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param multimap the multimap to be wrapped 7301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a synchronized view of the specified multimap 7311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 7320888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> SortedSetMultimap<K, V> 7330888a09821a98ac0680fad765217302858e70fa4Paul Duffin synchronizedSortedSetMultimap(SortedSetMultimap<K, V> multimap) { 7341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Synchronized.sortedSetMultimap(multimap, null); 7351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 7381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an unmodifiable view of the specified {@code SortedSetMultimap}. 7391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Query operations on the returned multimap "read through" to the specified 7401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap, and attempts to modify the returned multimap, either directly or 7411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * through the multimap's views, result in an 7421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code UnsupportedOperationException}. 7431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that the generated multimap's {@link Multimap#removeAll} and 7451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Multimap#replaceValues} methods return collections that are 7461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * modifiable. 7471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap will be serializable if the specified multimap is 7491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 7501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param delegate the multimap for which an unmodifiable view is to be 7521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned 7531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return an unmodifiable view of the specified multimap 7541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 7551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> SortedSetMultimap<K, V> unmodifiableSortedSetMultimap( 7561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedSetMultimap<K, V> delegate) { 7571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (delegate instanceof UnmodifiableSortedSetMultimap) { 7581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate; 7591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new UnmodifiableSortedSetMultimap<K, V>(delegate); 7611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 7641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a synchronized (thread-safe) {@code ListMultimap} backed by the 7651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * specified multimap. 7661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>You must follow the warnings described in {@link #synchronizedMultimap}. 7681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param multimap the multimap to be wrapped 7701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a synchronized view of the specified multimap 7711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 7720888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> ListMultimap<K, V> synchronizedListMultimap( 7730888a09821a98ac0680fad765217302858e70fa4Paul Duffin ListMultimap<K, V> multimap) { 7741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Synchronized.listMultimap(multimap, null); 7751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 7781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an unmodifiable view of the specified {@code ListMultimap}. Query 7791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * operations on the returned multimap "read through" to the specified 7801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap, and attempts to modify the returned multimap, either directly or 7811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * through the multimap's views, result in an 7821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code UnsupportedOperationException}. 7831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that the generated multimap's {@link Multimap#removeAll} and 7851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Multimap#replaceValues} methods return collections that are 7861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * modifiable. 7871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap will be serializable if the specified multimap is 7891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 7901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param delegate the multimap for which an unmodifiable view is to be 7921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned 7931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return an unmodifiable view of the specified multimap 7941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 7950888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> ListMultimap<K, V> unmodifiableListMultimap( 7960888a09821a98ac0680fad765217302858e70fa4Paul Duffin ListMultimap<K, V> delegate) { 7970888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (delegate instanceof UnmodifiableListMultimap || 7980888a09821a98ac0680fad765217302858e70fa4Paul Duffin delegate instanceof ImmutableListMultimap) { 7991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate; 8001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new UnmodifiableListMultimap<K, V>(delegate); 8021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 8051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Simply returns its argument. 8061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @deprecated no need to use this 8081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0 8091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 8100888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Deprecated public static <K, V> ListMultimap<K, V> unmodifiableListMultimap( 8111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ImmutableListMultimap<K, V> delegate) { 8121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return checkNotNull(delegate); 8131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 8161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an unmodifiable view of the specified collection, preserving the 8171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * interface for instances of {@code SortedSet}, {@code Set}, {@code List} and 8181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code Collection}, in that order of preference. 8191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param collection the collection for which to return an unmodifiable view 8211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return an unmodifiable view of the collection 8221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 8230888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static <V> Collection<V> unmodifiableValueCollection( 8240888a09821a98ac0680fad765217302858e70fa4Paul Duffin Collection<V> collection) { 8251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (collection instanceof SortedSet) { 8261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Collections.unmodifiableSortedSet((SortedSet<V>) collection); 8271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (collection instanceof Set) { 8281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Collections.unmodifiableSet((Set<V>) collection); 8291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (collection instanceof List) { 8301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Collections.unmodifiableList((List<V>) collection); 8311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Collections.unmodifiableCollection(collection); 8331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 8361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an unmodifiable view of the specified collection of entries. The 8371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Entry#setValue} operation throws an {@link 8381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * UnsupportedOperationException}. If the specified collection is a {@code 8391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Set}, the returned collection is also a {@code Set}. 8401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param entries the entries for which to return an unmodifiable view 8421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return an unmodifiable view of the entries 8431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 8440888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static <K, V> Collection<Entry<K, V>> unmodifiableEntries( 8450888a09821a98ac0680fad765217302858e70fa4Paul Duffin Collection<Entry<K, V>> entries) { 8461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (entries instanceof Set) { 8471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Maps.unmodifiableEntrySet((Set<Entry<K, V>>) entries); 8481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8490888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new Maps.UnmodifiableEntries<K, V>( 8500888a09821a98ac0680fad765217302858e70fa4Paul Duffin Collections.unmodifiableCollection(entries)); 8511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 8540888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Returns {@link ListMultimap#asMap multimap.asMap()}, with its type 8550888a09821a98ac0680fad765217302858e70fa4Paul Duffin * corrected from {@code Map<K, Collection<V>>} to {@code Map<K, List<V>>}. 8560888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 8570888a09821a98ac0680fad765217302858e70fa4Paul Duffin * @since 15.0 8581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 8590888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Beta 8600888a09821a98ac0680fad765217302858e70fa4Paul Duffin @SuppressWarnings("unchecked") 8610888a09821a98ac0680fad765217302858e70fa4Paul Duffin // safe by specification of ListMultimap.asMap() 8620888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> Map<K, List<V>> asMap(ListMultimap<K, V> multimap) { 8630888a09821a98ac0680fad765217302858e70fa4Paul Duffin return (Map<K, List<V>>) (Map<K, ?>) multimap.asMap(); 8641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8660888a09821a98ac0680fad765217302858e70fa4Paul Duffin /** 8670888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Returns {@link SetMultimap#asMap multimap.asMap()}, with its type corrected 8680888a09821a98ac0680fad765217302858e70fa4Paul Duffin * from {@code Map<K, Collection<V>>} to {@code Map<K, Set<V>>}. 8690888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 8700888a09821a98ac0680fad765217302858e70fa4Paul Duffin * @since 15.0 8710888a09821a98ac0680fad765217302858e70fa4Paul Duffin */ 8720888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Beta 8730888a09821a98ac0680fad765217302858e70fa4Paul Duffin @SuppressWarnings("unchecked") 8740888a09821a98ac0680fad765217302858e70fa4Paul Duffin // safe by specification of SetMultimap.asMap() 8750888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> Map<K, Set<V>> asMap(SetMultimap<K, V> multimap) { 8760888a09821a98ac0680fad765217302858e70fa4Paul Duffin return (Map<K, Set<V>>) (Map<K, ?>) multimap.asMap(); 8770888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 8781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8790888a09821a98ac0680fad765217302858e70fa4Paul Duffin /** 8800888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Returns {@link SortedSetMultimap#asMap multimap.asMap()}, with its type 8810888a09821a98ac0680fad765217302858e70fa4Paul Duffin * corrected from {@code Map<K, Collection<V>>} to 8820888a09821a98ac0680fad765217302858e70fa4Paul Duffin * {@code Map<K, SortedSet<V>>}. 8830888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 8840888a09821a98ac0680fad765217302858e70fa4Paul Duffin * @since 15.0 8850888a09821a98ac0680fad765217302858e70fa4Paul Duffin */ 8860888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Beta 8870888a09821a98ac0680fad765217302858e70fa4Paul Duffin @SuppressWarnings("unchecked") 8880888a09821a98ac0680fad765217302858e70fa4Paul Duffin // safe by specification of SortedSetMultimap.asMap() 8890888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> Map<K, SortedSet<V>> asMap( 8900888a09821a98ac0680fad765217302858e70fa4Paul Duffin SortedSetMultimap<K, V> multimap) { 8910888a09821a98ac0680fad765217302858e70fa4Paul Duffin return (Map<K, SortedSet<V>>) (Map<K, ?>) multimap.asMap(); 8920888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 8931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8940888a09821a98ac0680fad765217302858e70fa4Paul Duffin /** 8950888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Returns {@link Multimap#asMap multimap.asMap()}. This is provided for 8960888a09821a98ac0680fad765217302858e70fa4Paul Duffin * parity with the other more strongly-typed {@code asMap()} implementations. 8970888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 8980888a09821a98ac0680fad765217302858e70fa4Paul Duffin * @since 15.0 8990888a09821a98ac0680fad765217302858e70fa4Paul Duffin */ 9000888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Beta 9010888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> Map<K, Collection<V>> asMap(Multimap<K, V> multimap) { 9020888a09821a98ac0680fad765217302858e70fa4Paul Duffin return multimap.asMap(); 9031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 9061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a multimap view of the specified map. The multimap is backed by the 9071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * map, so changes to the map are reflected in the multimap, and vice versa. 9081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * If the map is modified while an iteration over one of the multimap's 9091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * collection views is in progress (except through the iterator's own {@code 9101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * remove} operation, or through the {@code setValue} operation on a map entry 9111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned by the iterator), the results of the iteration are undefined. 9121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 9131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The multimap supports mapping removal, which removes the corresponding 9141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * mapping from the map. It does not support any operations which might add 9151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * mappings, such as {@code put}, {@code putAll} or {@code replaceValues}. 9161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 9171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap will be serializable if the specified map is 9181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 9191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 9201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param map the backing map for the returned multimap view 9211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 9221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> SetMultimap<K, V> forMap(Map<K, V> map) { 9231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new MapMultimap<K, V>(map); 9241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @see Multimaps#forMap */ 9270888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static class MapMultimap<K, V> 9280888a09821a98ac0680fad765217302858e70fa4Paul Duffin extends AbstractMultimap<K, V> implements SetMultimap<K, V>, Serializable { 9291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map<K, V> map; 9301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MapMultimap(Map<K, V> map) { 9321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.map = checkNotNull(map); 9331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9350888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 9361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public int size() { 9371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.size(); 9381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9400888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 9411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean containsKey(Object key) { 9421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.containsKey(key); 9431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9450888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 9461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean containsValue(Object value) { 9471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.containsValue(value); 9481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9500888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 9511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean containsEntry(Object key, Object value) { 9521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.entrySet().contains(Maps.immutableEntry(key, value)); 9531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9550888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 9561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Set<V> get(final K key) { 9577dd252788645e940eada959bdde927426e2531c9Paul Duffin return new Sets.ImprovedAbstractSet<V>() { 9580888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Iterator<V> iterator() { 9591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Iterator<V>() { 9601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int i; 9611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9620888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 9631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean hasNext() { 9641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (i == 0) && map.containsKey(key); 9651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9670888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 9681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V next() { 9691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!hasNext()) { 9701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new NoSuchElementException(); 9711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert i++; 9731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.get(key); 9741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9760888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 9771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void remove() { 9780888a09821a98ac0680fad765217302858e70fa4Paul Duffin checkRemove(i == 1); 9791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert i = -1; 9801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.remove(key); 9811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 9831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9850888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public int size() { 9861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.containsKey(key) ? 1 : 0; 9871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 9891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9910888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 9921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean put(K key, V value) { 9931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 9941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9960888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 9971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean putAll(K key, Iterable<? extends V> values) { 9981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 9991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10010888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 10021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean putAll(Multimap<? extends K, ? extends V> multimap) { 10031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 10041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10060888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 10071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Set<V> replaceValues(K key, Iterable<? extends V> values) { 10081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 10091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10110888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 10121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean remove(Object key, Object value) { 10131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.entrySet().remove(Maps.immutableEntry(key, value)); 10141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10160888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 10171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Set<V> removeAll(Object key) { 10181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<V> values = new HashSet<V>(2); 10191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!map.containsKey(key)) { 10201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return values; 10211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert values.add(map.remove(key)); 10231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return values; 10241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10260888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 10271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void clear() { 10281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.clear(); 10291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10310888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 10321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Set<K> keySet() { 10331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.keySet(); 10341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10360888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 10371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Collection<V> values() { 10381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.values(); 10391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10410888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 10421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Set<Entry<K, V>> entries() { 10431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return map.entrySet(); 10441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10450888a09821a98ac0680fad765217302858e70fa4Paul Duffin 10467dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 10470888a09821a98ac0680fad765217302858e70fa4Paul Duffin Iterator<Entry<K, V>> entryIterator() { 10480888a09821a98ac0680fad765217302858e70fa4Paul Duffin return map.entrySet().iterator(); 10491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10517dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 10520888a09821a98ac0680fad765217302858e70fa4Paul Duffin Map<K, Collection<V>> createAsMap() { 10530888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new AsMap<K, V>(this); 10541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10560888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public int hashCode() { 10570888a09821a98ac0680fad765217302858e70fa4Paul Duffin return map.hashCode(); 10581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10590888a09821a98ac0680fad765217302858e70fa4Paul Duffin 10601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 7845222491160860175L; 10611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 10641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a view of a multimap where each value is transformed by a function. 10651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * All other properties of the multimap, such as iteration order, are left 10661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * intact. For example, the code: <pre> {@code 10671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimap<String, Integer> multimap = 10691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableSetMultimap.of("a", 2, "b", -3, "b", -3, "a", 4, "c", 6); 10701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Function<Integer, String> square = new Function<Integer, String>() { 10711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * public String apply(Integer in) { 10721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * return Integer.toString(in * in); 10731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * } 10741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * }; 10751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimap<String, String> transformed = 10761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimaps.transformValues(multimap, square); 10771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * System.out.println(transformed);}</pre> 10781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10790888a09821a98ac0680fad765217302858e70fa4Paul Duffin * ... prints {@code {a=[4, 16], b=[9, 9], c=[36]}}. 10801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Changes in the underlying multimap are reflected in this view. 10821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Conversely, this view supports removal operations, and these are reflected 10831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * in the underlying multimap. 10841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>It's acceptable for the underlying multimap to contain null keys, and 10861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * even null values provided that the function is capable of accepting null 10871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * input. The transformed multimap might contain null values, if the function 10881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * sometimes gives a null result. 10891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap is not thread-safe or serializable, even if the 10911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * underlying multimap is. The {@code equals} and {@code hashCode} methods 10921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * of the returned multimap are meaningless, since there is not a definition 10931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * of {@code equals} or {@code hashCode} for general collections, and 10941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code get()} will return a general {@code Collection} as opposed to a 10951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code List} or a {@code Set}. 10961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 10971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The function is applied lazily, invoked when needed. This is necessary 10981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * for the returned multimap to be a view, but it means that the function will 10991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * be applied many times for bulk operations like 11001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Multimap#containsValue} and {@code Multimap.toString()}. For this to 11011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * perform well, {@code function} should be fast. To avoid lazy evaluation 11021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * when the returned multimap doesn't need to be a view, copy the returned 11031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap into a new multimap of your choosing. 11041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 11051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 7.0 11061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 11070888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V1, V2> Multimap<K, V2> transformValues( 11080888a09821a98ac0680fad765217302858e70fa4Paul Duffin Multimap<K, V1> fromMultimap, final Function<? super V1, V2> function) { 11091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(function); 11100888a09821a98ac0680fad765217302858e70fa4Paul Duffin EntryTransformer<K, V1, V2> transformer = Maps.asEntryTransformer(function); 11111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transformEntries(fromMultimap, transformer); 11121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 11151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a view of a multimap whose values are derived from the original 11161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap's entries. In contrast to {@link #transformValues}, this method's 11171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * entry-transformation logic may depend on the key as well as the value. 11181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 11191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>All other properties of the transformed multimap, such as iteration 11201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * order, are left intact. For example, the code: <pre> {@code 11211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 11221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * SetMultimap<String, Integer> multimap = 11231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableSetMultimap.of("a", 1, "a", 4, "b", -6); 11241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * EntryTransformer<String, Integer, String> transformer = 11251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * new EntryTransformer<String, Integer, String>() { 11261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * public String transformEntry(String key, Integer value) { 11271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * return (value >= 0) ? key : "no" + key; 11281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * } 11291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * }; 11301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimap<String, String> transformed = 11311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimaps.transformEntries(multimap, transformer); 11321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * System.out.println(transformed);}</pre> 11331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 11341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ... prints {@code {a=[a, a], b=[nob]}}. 11351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 11361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Changes in the underlying multimap are reflected in this view. 11371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Conversely, this view supports removal operations, and these are reflected 11381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * in the underlying multimap. 11391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 11401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>It's acceptable for the underlying multimap to contain null keys and 11411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * null values provided that the transformer is capable of accepting null 11421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * inputs. The transformed multimap might contain null values if the 11431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * transformer sometimes gives a null result. 11441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 11451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap is not thread-safe or serializable, even if the 11461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * underlying multimap is. The {@code equals} and {@code hashCode} methods 11471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * of the returned multimap are meaningless, since there is not a definition 11481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * of {@code equals} or {@code hashCode} for general collections, and 11491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code get()} will return a general {@code Collection} as opposed to a 11501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code List} or a {@code Set}. 11511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 11521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The transformer is applied lazily, invoked when needed. This is 11531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * necessary for the returned multimap to be a view, but it means that the 11541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * transformer will be applied many times for bulk operations like {@link 11551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimap#containsValue} and {@link Object#toString}. For this to perform 11561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * well, {@code transformer} should be fast. To avoid lazy evaluation when the 11571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned multimap doesn't need to be a view, copy the returned multimap 11581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * into a new multimap of your choosing. 11591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 11601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> This method assumes that for any instance {@code k} of 11611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies 11621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * that {@code k2} is also of type {@code K}. Using an {@code 11631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * EntryTransformer} key type for which this may not hold, such as {@code 11641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ArrayList}, may risk a {@code ClassCastException} when calling methods on 11651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the transformed multimap. 11661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 11671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 7.0 11681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 11690888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V1, V2> Multimap<K, V2> transformEntries( 11700888a09821a98ac0680fad765217302858e70fa4Paul Duffin Multimap<K, V1> fromMap, 11711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryTransformer<? super K, ? super V1, V2> transformer) { 11721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new TransformedEntriesMultimap<K, V1, V2>(fromMap, transformer); 11731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11750888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static class TransformedEntriesMultimap<K, V1, V2> 11760888a09821a98ac0680fad765217302858e70fa4Paul Duffin extends AbstractMultimap<K, V2> { 11771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Multimap<K, V1> fromMultimap; 11781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final EntryTransformer<? super K, ? super V1, V2> transformer; 11791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert TransformedEntriesMultimap(Multimap<K, V1> fromMultimap, 11811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final EntryTransformer<? super K, ? super V1, V2> transformer) { 11821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.fromMultimap = checkNotNull(fromMultimap); 11831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.transformer = checkNotNull(transformer); 11841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11867dd252788645e940eada959bdde927426e2531c9Paul Duffin Collection<V2> transform(K key, Collection<V1> values) { 11870888a09821a98ac0680fad765217302858e70fa4Paul Duffin Function<? super V1, V2> function = 11880888a09821a98ac0680fad765217302858e70fa4Paul Duffin Maps.asValueToValueFunction(transformer, key); 11897dd252788645e940eada959bdde927426e2531c9Paul Duffin if (values instanceof List) { 11907dd252788645e940eada959bdde927426e2531c9Paul Duffin return Lists.transform((List<V1>) values, function); 11917dd252788645e940eada959bdde927426e2531c9Paul Duffin } else { 11927dd252788645e940eada959bdde927426e2531c9Paul Duffin return Collections2.transform(values, function); 11937dd252788645e940eada959bdde927426e2531c9Paul Duffin } 11941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11967dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 11977dd252788645e940eada959bdde927426e2531c9Paul Duffin Map<K, Collection<V2>> createAsMap() { 11987dd252788645e940eada959bdde927426e2531c9Paul Duffin return Maps.transformEntries(fromMultimap.asMap(), 11997dd252788645e940eada959bdde927426e2531c9Paul Duffin new EntryTransformer<K, Collection<V1>, Collection<V2>>() { 12000888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Collection<V2> transformEntry( 12010888a09821a98ac0680fad765217302858e70fa4Paul Duffin K key, Collection<V1> value) { 12020888a09821a98ac0680fad765217302858e70fa4Paul Duffin return transform(key, value); 12030888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 12040888a09821a98ac0680fad765217302858e70fa4Paul Duffin }); 12051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12070888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public void clear() { 12081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fromMultimap.clear(); 12091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12110888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean containsKey(Object key) { 12121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMultimap.containsKey(key); 12131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12157dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 12167dd252788645e940eada959bdde927426e2531c9Paul Duffin Iterator<Entry<K, V2>> entryIterator() { 12170888a09821a98ac0680fad765217302858e70fa4Paul Duffin return Iterators.transform(fromMultimap.entries().iterator(), 12180888a09821a98ac0680fad765217302858e70fa4Paul Duffin Maps.<K, V1, V2>asEntryToEntryFunction(transformer)); 12191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12210888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Collection<V2> get(final K key) { 12221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transform(key, fromMultimap.get(key)); 12231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12250888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean isEmpty() { 12261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMultimap.isEmpty(); 12271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12290888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Set<K> keySet() { 12301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMultimap.keySet(); 12311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12330888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Multiset<K> keys() { 12341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMultimap.keys(); 12351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12370888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean put(K key, V2 value) { 12381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 12391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12410888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean putAll(K key, Iterable<? extends V2> values) { 12421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 12431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12450888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean putAll( 12460888a09821a98ac0680fad765217302858e70fa4Paul Duffin Multimap<? extends K, ? extends V2> multimap) { 12471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 12481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 12510888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean remove(Object key, Object value) { 12521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return get((K) key).remove(value); 12531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 12560888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Collection<V2> removeAll(Object key) { 12571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transform((K) key, fromMultimap.removeAll(key)); 12581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12600888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Collection<V2> replaceValues( 12610888a09821a98ac0680fad765217302858e70fa4Paul Duffin K key, Iterable<? extends V2> values) { 12621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 12631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12650888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public int size() { 12661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return fromMultimap.size(); 12671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12680888a09821a98ac0680fad765217302858e70fa4Paul Duffin 12697dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 12707dd252788645e940eada959bdde927426e2531c9Paul Duffin Collection<V2> createValues() { 12710888a09821a98ac0680fad765217302858e70fa4Paul Duffin return Collections2.transform( 12720888a09821a98ac0680fad765217302858e70fa4Paul Duffin fromMultimap.entries(), Maps.<K, V1, V2>asEntryToValueFunction(transformer)); 12731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 12771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a view of a {@code ListMultimap} where each value is transformed by 12781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * a function. All other properties of the multimap, such as iteration order, 12791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * are left intact. For example, the code: <pre> {@code 12801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 12811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ListMultimap<String, Integer> multimap 12821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * = ImmutableListMultimap.of("a", 4, "a", 16, "b", 9); 12831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Function<Integer, Double> sqrt = 12841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * new Function<Integer, Double>() { 12851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * public Double apply(Integer in) { 12861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * return Math.sqrt((int) in); 12871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * } 12881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * }; 12891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ListMultimap<String, Double> transformed = Multimaps.transformValues(map, 12901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * sqrt); 12911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * System.out.println(transformed);}</pre> 12921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 12931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ... prints {@code {a=[2.0, 4.0], b=[3.0]}}. 12941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 12951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Changes in the underlying multimap are reflected in this view. 12961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Conversely, this view supports removal operations, and these are reflected 12971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * in the underlying multimap. 12981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 12991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>It's acceptable for the underlying multimap to contain null keys, and 13001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * even null values provided that the function is capable of accepting null 13011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * input. The transformed multimap might contain null values, if the function 13021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * sometimes gives a null result. 13031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap is not thread-safe or serializable, even if the 13051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * underlying multimap is. 13061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The function is applied lazily, invoked when needed. This is necessary 13081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * for the returned multimap to be a view, but it means that the function will 13091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * be applied many times for bulk operations like 13101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Multimap#containsValue} and {@code Multimap.toString()}. For this to 13111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * perform well, {@code function} should be fast. To avoid lazy evaluation 13121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * when the returned multimap doesn't need to be a view, copy the returned 13131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap into a new multimap of your choosing. 13141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 7.0 13161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 13170888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V1, V2> ListMultimap<K, V2> transformValues( 13180888a09821a98ac0680fad765217302858e70fa4Paul Duffin ListMultimap<K, V1> fromMultimap, 13191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Function<? super V1, V2> function) { 13201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(function); 13210888a09821a98ac0680fad765217302858e70fa4Paul Duffin EntryTransformer<K, V1, V2> transformer = Maps.asEntryTransformer(function); 13221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transformEntries(fromMultimap, transformer); 13231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 13241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 13251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 13261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a view of a {@code ListMultimap} whose values are derived from the 13271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * original multimap's entries. In contrast to 13281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link #transformValues(ListMultimap, Function)}, this method's 13291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * entry-transformation logic may depend on the key as well as the value. 13301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>All other properties of the transformed multimap, such as iteration 13321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * order, are left intact. For example, the code: <pre> {@code 13331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimap<String, Integer> multimap = 13351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableMultimap.of("a", 1, "a", 4, "b", 6); 13361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * EntryTransformer<String, Integer, String> transformer = 13371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * new EntryTransformer<String, Integer, String>() { 13381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * public String transformEntry(String key, Integer value) { 13391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * return key + value; 13401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * } 13411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * }; 13421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimap<String, String> transformed = 13431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimaps.transformEntries(multimap, transformer); 13441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * System.out.println(transformed);}</pre> 13451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ... prints {@code {"a"=["a1", "a4"], "b"=["b6"]}}. 13471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Changes in the underlying multimap are reflected in this view. 13491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Conversely, this view supports removal operations, and these are reflected 13501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * in the underlying multimap. 13511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>It's acceptable for the underlying multimap to contain null keys and 13531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * null values provided that the transformer is capable of accepting null 13541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * inputs. The transformed multimap might contain null values if the 13551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * transformer sometimes gives a null result. 13561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap is not thread-safe or serializable, even if the 13581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * underlying multimap is. 13591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The transformer is applied lazily, invoked when needed. This is 13611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * necessary for the returned multimap to be a view, but it means that the 13621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * transformer will be applied many times for bulk operations like {@link 13631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimap#containsValue} and {@link Object#toString}. For this to perform 13641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * well, {@code transformer} should be fast. To avoid lazy evaluation when the 13651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned multimap doesn't need to be a view, copy the returned multimap 13661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * into a new multimap of your choosing. 13671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> This method assumes that for any instance {@code k} of 13691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies 13701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * that {@code k2} is also of type {@code K}. Using an {@code 13711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * EntryTransformer} key type for which this may not hold, such as {@code 13721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ArrayList}, may risk a {@code ClassCastException} when calling methods on 13731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the transformed multimap. 13741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 13751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 7.0 13761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 13770888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V1, V2> ListMultimap<K, V2> transformEntries( 13780888a09821a98ac0680fad765217302858e70fa4Paul Duffin ListMultimap<K, V1> fromMap, 13791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryTransformer<? super K, ? super V1, V2> transformer) { 13801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new TransformedEntriesListMultimap<K, V1, V2>(fromMap, transformer); 13811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 13821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 13830888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static final class TransformedEntriesListMultimap<K, V1, V2> 13840888a09821a98ac0680fad765217302858e70fa4Paul Duffin extends TransformedEntriesMultimap<K, V1, V2> 13850888a09821a98ac0680fad765217302858e70fa4Paul Duffin implements ListMultimap<K, V2> { 13861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 13871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert TransformedEntriesListMultimap(ListMultimap<K, V1> fromMultimap, 13881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryTransformer<? super K, ? super V1, V2> transformer) { 13891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(fromMultimap, transformer); 13901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 13911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 13920888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override List<V2> transform(K key, Collection<V1> values) { 13930888a09821a98ac0680fad765217302858e70fa4Paul Duffin return Lists.transform((List<V1>) values, Maps.asValueToValueFunction(transformer, key)); 13941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 13951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 13960888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public List<V2> get(K key) { 13971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transform(key, fromMultimap.get(key)); 13981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 13991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 14010888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public List<V2> removeAll(Object key) { 14021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return transform((K) key, fromMultimap.removeAll(key)); 14031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14050888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public List<V2> replaceValues( 14060888a09821a98ac0680fad765217302858e70fa4Paul Duffin K key, Iterable<? extends V2> values) { 14071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 14081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 14121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates an index {@code ImmutableListMultimap} that contains the results of 14131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * applying a specified function to each item in an {@code Iterable} of 14141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values. Each value will be stored as a value in the resulting multimap, 14151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * yielding a multimap with the same size as the input iterable. The key used 14161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * to store that value in the multimap will be the result of calling the 14171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * function on that value. The resulting multimap is created as an immutable 14181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * snapshot. In the returned multimap, keys appear in the order they are first 14191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * encountered, and the values corresponding to each key appear in the same 14201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * order as they are encountered. 14211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>For example, <pre> {@code 14231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * List<String> badGuys = 14251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde"); 14261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Function<String, Integer> stringLengthFunction = ...; 14271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimap<Integer, String> index = 14281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimaps.index(badGuys, stringLengthFunction); 14291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * System.out.println(index);}</pre> 14301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14310888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>prints <pre> {@code 14321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {4=[Inky], 6=[Blinky], 5=[Pinky, Pinky, Clyde]}}</pre> 14341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14350888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>The returned multimap is serializable if its keys and values are all 14361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 14371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param values the values to use when constructing the {@code 14391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableListMultimap} 14401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param keyFunction the function used to produce the key for each value 14411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return {@code ImmutableListMultimap} mapping the result of evaluating the 14421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * function {@code keyFunction} on each value in the input collection to 14431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * that value 14441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws NullPointerException if any of the following cases is true: 14451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <ul> 14461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>{@code values} is null 14471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>{@code keyFunction} is null 14481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>An element in {@code values} is null 14491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>{@code keyFunction} returns {@code null} for any element of {@code 14501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values} 14511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * </ul> 14521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 14530888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> ImmutableListMultimap<K, V> index( 14540888a09821a98ac0680fad765217302858e70fa4Paul Duffin Iterable<V> values, Function<? super V, K> keyFunction) { 14551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return index(values.iterator(), keyFunction); 14561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 14591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates an index {@code ImmutableListMultimap} that contains the results of 14601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * applying a specified function to each item in an {@code Iterator} of 14611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values. Each value will be stored as a value in the resulting multimap, 14621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * yielding a multimap with the same size as the input iterator. The key used 14631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * to store that value in the multimap will be the result of calling the 14641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * function on that value. The resulting multimap is created as an immutable 14651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * snapshot. In the returned multimap, keys appear in the order they are first 14661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * encountered, and the values corresponding to each key appear in the same 14671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * order as they are encountered. 14681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>For example, <pre> {@code 14701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * List<String> badGuys = 14721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde"); 14731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Function<String, Integer> stringLengthFunction = ...; 14741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimap<Integer, String> index = 14751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multimaps.index(badGuys.iterator(), stringLengthFunction); 14761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * System.out.println(index);}</pre> 14771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14780888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>prints <pre> {@code 14791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {4=[Inky], 6=[Blinky], 5=[Pinky, Pinky, Clyde]}}</pre> 14811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14820888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>The returned multimap is serializable if its keys and values are all 14831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serializable. 14841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 14851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param values the values to use when constructing the {@code 14861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ImmutableListMultimap} 14871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param keyFunction the function used to produce the key for each value 14881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return {@code ImmutableListMultimap} mapping the result of evaluating the 14891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * function {@code keyFunction} on each value in the input collection to 14901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * that value 14911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws NullPointerException if any of the following cases is true: 14921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <ul> 14931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>{@code values} is null 14941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>{@code keyFunction} is null 14951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>An element in {@code values} is null 14961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>{@code keyFunction} returns {@code null} for any element of {@code 14971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values} 14981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * </ul> 14991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0 15001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 15010888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> ImmutableListMultimap<K, V> index( 15020888a09821a98ac0680fad765217302858e70fa4Paul Duffin Iterator<V> values, Function<? super V, K> keyFunction) { 15031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(keyFunction); 15040888a09821a98ac0680fad765217302858e70fa4Paul Duffin ImmutableListMultimap.Builder<K, V> builder 15050888a09821a98ac0680fad765217302858e70fa4Paul Duffin = ImmutableListMultimap.builder(); 15061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (values.hasNext()) { 15071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V value = values.next(); 15081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(value, values); 15091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert builder.put(keyFunction.apply(value), value); 15101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return builder.build(); 15121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15147dd252788645e940eada959bdde927426e2531c9Paul Duffin static class Keys<K, V> extends AbstractMultiset<K> { 15157dd252788645e940eada959bdde927426e2531c9Paul Duffin final Multimap<K, V> multimap; 15167dd252788645e940eada959bdde927426e2531c9Paul Duffin 15177dd252788645e940eada959bdde927426e2531c9Paul Duffin Keys(Multimap<K, V> multimap) { 15187dd252788645e940eada959bdde927426e2531c9Paul Duffin this.multimap = multimap; 15197dd252788645e940eada959bdde927426e2531c9Paul Duffin } 15201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Iterator<Multiset.Entry<K>> entryIterator() { 15227dd252788645e940eada959bdde927426e2531c9Paul Duffin return new TransformedIterator<Map.Entry<K, Collection<V>>, Multiset.Entry<K>>( 15237dd252788645e940eada959bdde927426e2531c9Paul Duffin multimap.asMap().entrySet().iterator()) { 15247dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 15250888a09821a98ac0680fad765217302858e70fa4Paul Duffin Multiset.Entry<K> transform( 15260888a09821a98ac0680fad765217302858e70fa4Paul Duffin final Map.Entry<K, Collection<V>> backingEntry) { 15271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Multisets.AbstractEntry<K>() { 15280888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 15297dd252788645e940eada959bdde927426e2531c9Paul Duffin public K getElement() { 15301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return backingEntry.getKey(); 15311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15330888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 15347dd252788645e940eada959bdde927426e2531c9Paul Duffin public int getCount() { 15351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return backingEntry.getValue().size(); 15361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 15381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 15401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override int distinctElements() { 15437dd252788645e940eada959bdde927426e2531c9Paul Duffin return multimap.asMap().size(); 15441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15460888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override Set<Multiset.Entry<K>> createEntrySet() { 15471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new KeysEntrySet(); 15481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class KeysEntrySet extends Multisets.EntrySet<K> { 15510888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override Multiset<K> multiset() { 15521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Keys.this; 15531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15550888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Iterator<Multiset.Entry<K>> iterator() { 15561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entryIterator(); 15571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15590888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public int size() { 15601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return distinctElements(); 15611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean isEmpty() { 15647dd252788645e940eada959bdde927426e2531c9Paul Duffin return multimap.isEmpty(); 15651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15670888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean contains(@Nullable Object o) { 15687dd252788645e940eada959bdde927426e2531c9Paul Duffin if (o instanceof Multiset.Entry) { 15691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multiset.Entry<?> entry = (Multiset.Entry<?>) o; 15707dd252788645e940eada959bdde927426e2531c9Paul Duffin Collection<V> collection = multimap.asMap().get(entry.getElement()); 15711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return collection != null && collection.size() == entry.getCount(); 15721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 15741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15760888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean remove(@Nullable Object o) { 15777dd252788645e940eada959bdde927426e2531c9Paul Duffin if (o instanceof Multiset.Entry) { 15781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multiset.Entry<?> entry = (Multiset.Entry<?>) o; 15797dd252788645e940eada959bdde927426e2531c9Paul Duffin Collection<V> collection = multimap.asMap().get(entry.getElement()); 15801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (collection != null && collection.size() == entry.getCount()) { 15811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert collection.clear(); 15821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 15831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 15861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(@Nullable Object element) { 15907dd252788645e940eada959bdde927426e2531c9Paul Duffin return multimap.containsKey(element); 15911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<K> iterator() { 15947dd252788645e940eada959bdde927426e2531c9Paul Duffin return Maps.keyIterator(multimap.entries().iterator()); 15951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int count(@Nullable Object element) { 15987dd252788645e940eada959bdde927426e2531c9Paul Duffin Collection<V> values = Maps.safeGet(multimap.asMap(), element); 15997dd252788645e940eada959bdde927426e2531c9Paul Duffin return (values == null) ? 0 : values.size(); 16001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16020888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public int remove(@Nullable Object element, int occurrences) { 16030888a09821a98ac0680fad765217302858e70fa4Paul Duffin checkNonnegative(occurrences, "occurrences"); 16041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (occurrences == 0) { 16051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return count(element); 16061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16087dd252788645e940eada959bdde927426e2531c9Paul Duffin Collection<V> values = Maps.safeGet(multimap.asMap(), element); 16091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (values == null) { 16111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 0; 16121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int oldCount = values.size(); 16151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (occurrences >= oldCount) { 16161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert values.clear(); 16171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 16181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<V> iterator = values.iterator(); 16191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < occurrences; i++) { 16201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.next(); 16211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 16221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return oldCount; 16251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void clear() { 16287dd252788645e940eada959bdde927426e2531c9Paul Duffin multimap.clear(); 16291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<K> elementSet() { 16327dd252788645e940eada959bdde927426e2531c9Paul Duffin return multimap.keySet(); 16331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 16371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * A skeleton implementation of {@link Multimap#entries()}. 16381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 16390888a09821a98ac0680fad765217302858e70fa4Paul Duffin abstract static class Entries<K, V> extends 16400888a09821a98ac0680fad765217302858e70fa4Paul Duffin AbstractCollection<Map.Entry<K, V>> { 16411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract Multimap<K, V> multimap(); 16421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16430888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public int size() { 16441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return multimap().size(); 16451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16470888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean contains(@Nullable Object o) { 16487dd252788645e940eada959bdde927426e2531c9Paul Duffin if (o instanceof Map.Entry) { 16491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o; 16501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return multimap().containsEntry(entry.getKey(), entry.getValue()); 16511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 16531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16550888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean remove(@Nullable Object o) { 16567dd252788645e940eada959bdde927426e2531c9Paul Duffin if (o instanceof Map.Entry) { 16571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o; 16581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return multimap().remove(entry.getKey(), entry.getValue()); 16591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 16611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16630888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public void clear() { 16641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert multimap().clear(); 16651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 16690888a09821a98ac0680fad765217302858e70fa4Paul Duffin * A skeleton implementation of {@link Multimap#asMap()}. 16701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 16710888a09821a98ac0680fad765217302858e70fa4Paul Duffin static final class AsMap<K, V> extends 16720888a09821a98ac0680fad765217302858e70fa4Paul Duffin Maps.ImprovedAbstractMap<K, Collection<V>> { 16730888a09821a98ac0680fad765217302858e70fa4Paul Duffin private final Multimap<K, V> multimap; 16740888a09821a98ac0680fad765217302858e70fa4Paul Duffin 16750888a09821a98ac0680fad765217302858e70fa4Paul Duffin AsMap(Multimap<K, V> multimap) { 16760888a09821a98ac0680fad765217302858e70fa4Paul Duffin this.multimap = checkNotNull(multimap); 16771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16790888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public int size() { 16800888a09821a98ac0680fad765217302858e70fa4Paul Duffin return multimap.keySet().size(); 16811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16830888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override protected Set<Entry<K, Collection<V>>> createEntrySet() { 16841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new EntrySet(); 16851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16877dd252788645e940eada959bdde927426e2531c9Paul Duffin void removeValuesForKey(Object key) { 16880888a09821a98ac0680fad765217302858e70fa4Paul Duffin multimap.keySet().remove(key); 16891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class EntrySet extends Maps.EntrySet<K, Collection<V>> { 16920888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override Map<K, Collection<V>> map() { 16931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return AsMap.this; 16941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16960888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Iterator<Entry<K, Collection<V>>> iterator() { 16970888a09821a98ac0680fad765217302858e70fa4Paul Duffin return Maps.asMapEntryIterator(multimap.keySet(), new Function<K, Collection<V>>() { 16980888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 16990888a09821a98ac0680fad765217302858e70fa4Paul Duffin public Collection<V> apply(K key) { 17000888a09821a98ac0680fad765217302858e70fa4Paul Duffin return multimap.get(key); 17010888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 17020888a09821a98ac0680fad765217302858e70fa4Paul Duffin }); 17031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17050888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean remove(Object o) { 17061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!contains(o)) { 17071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 17081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o; 17101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert removeValuesForKey(entry.getKey()); 17111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 17121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 17160888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Collection<V> get(Object key) { 17170888a09821a98ac0680fad765217302858e70fa4Paul Duffin return containsKey(key) ? multimap.get((K) key) : null; 17181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17200888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Collection<V> remove(Object key) { 17210888a09821a98ac0680fad765217302858e70fa4Paul Duffin return containsKey(key) ? multimap.removeAll(key) : null; 17221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17240888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Set<K> keySet() { 17250888a09821a98ac0680fad765217302858e70fa4Paul Duffin return multimap.keySet(); 17261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17280888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean isEmpty() { 17290888a09821a98ac0680fad765217302858e70fa4Paul Duffin return multimap.isEmpty(); 17301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17320888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean containsKey(Object key) { 17330888a09821a98ac0680fad765217302858e70fa4Paul Duffin return multimap.containsKey(key); 17341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17360888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public void clear() { 17370888a09821a98ac0680fad765217302858e70fa4Paul Duffin multimap.clear(); 17381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 17421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a multimap containing the mappings in {@code unfiltered} whose keys 17431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * satisfy a predicate. The returned multimap is a live view of 17441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code unfiltered}; changes to one affect the other. 17451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 17461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The resulting multimap's views have iterators that don't support 17471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code remove()}, but all other methods are supported by the multimap and 17481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * its views. When adding a key that doesn't satisfy the predicate, the 17497dd252788645e940eada959bdde927426e2531c9Paul Duffin * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()} 17507dd252788645e940eada959bdde927426e2531c9Paul Duffin * methods throw an {@link IllegalArgumentException}. 17511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 17521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When methods such as {@code removeAll()} and {@code clear()} are called on 17531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the filtered multimap or its views, only mappings whose keys satisfy the 17541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * filter will be removed from the underlying multimap. 17551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 17561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap isn't threadsafe or serializable, even if 17571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code unfiltered} is. 17581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 17591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate 17601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * across every key/value mapping in the underlying multimap and determine 17611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * which satisfy the filter. When a live view is <i>not</i> needed, it may be 17621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * faster to copy the filtered multimap and use the copy. 17631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 17641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>, 17651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * as documented at {@link Predicate#apply}. Do not provide a predicate such 17661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent 17671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * with equals. 17681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 17691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 17701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 17710888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> Multimap<K, V> filterKeys( 17720888a09821a98ac0680fad765217302858e70fa4Paul Duffin Multimap<K, V> unfiltered, final Predicate<? super K> keyPredicate) { 17730888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (unfiltered instanceof SetMultimap) { 17740888a09821a98ac0680fad765217302858e70fa4Paul Duffin return filterKeys((SetMultimap<K, V>) unfiltered, keyPredicate); 17750888a09821a98ac0680fad765217302858e70fa4Paul Duffin } else if (unfiltered instanceof ListMultimap) { 17760888a09821a98ac0680fad765217302858e70fa4Paul Duffin return filterKeys((ListMultimap<K, V>) unfiltered, keyPredicate); 17770888a09821a98ac0680fad765217302858e70fa4Paul Duffin } else if (unfiltered instanceof FilteredKeyMultimap) { 17787dd252788645e940eada959bdde927426e2531c9Paul Duffin FilteredKeyMultimap<K, V> prev = (FilteredKeyMultimap<K, V>) unfiltered; 17790888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new FilteredKeyMultimap<K, V>(prev.unfiltered, 17800888a09821a98ac0680fad765217302858e70fa4Paul Duffin Predicates.and(prev.keyPredicate, keyPredicate)); 17817dd252788645e940eada959bdde927426e2531c9Paul Duffin } else if (unfiltered instanceof FilteredMultimap) { 17827dd252788645e940eada959bdde927426e2531c9Paul Duffin FilteredMultimap<K, V> prev = (FilteredMultimap<K, V>) unfiltered; 17830888a09821a98ac0680fad765217302858e70fa4Paul Duffin return filterFiltered(prev, Maps.<K>keyPredicateOnEntries(keyPredicate)); 17847dd252788645e940eada959bdde927426e2531c9Paul Duffin } else { 17857dd252788645e940eada959bdde927426e2531c9Paul Duffin return new FilteredKeyMultimap<K, V>(unfiltered, keyPredicate); 17867dd252788645e940eada959bdde927426e2531c9Paul Duffin } 17871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17880888a09821a98ac0680fad765217302858e70fa4Paul Duffin 17890888a09821a98ac0680fad765217302858e70fa4Paul Duffin /** 17900888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Returns a multimap containing the mappings in {@code unfiltered} whose keys 17910888a09821a98ac0680fad765217302858e70fa4Paul Duffin * satisfy a predicate. The returned multimap is a live view of 17920888a09821a98ac0680fad765217302858e70fa4Paul Duffin * {@code unfiltered}; changes to one affect the other. 17930888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 17940888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>The resulting multimap's views have iterators that don't support 17950888a09821a98ac0680fad765217302858e70fa4Paul Duffin * {@code remove()}, but all other methods are supported by the multimap and 17960888a09821a98ac0680fad765217302858e70fa4Paul Duffin * its views. When adding a key that doesn't satisfy the predicate, the 17970888a09821a98ac0680fad765217302858e70fa4Paul Duffin * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()} 17980888a09821a98ac0680fad765217302858e70fa4Paul Duffin * methods throw an {@link IllegalArgumentException}. 17990888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 18000888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>When methods such as {@code removeAll()} and {@code clear()} are called on 18010888a09821a98ac0680fad765217302858e70fa4Paul Duffin * the filtered multimap or its views, only mappings whose keys satisfy the 18020888a09821a98ac0680fad765217302858e70fa4Paul Duffin * filter will be removed from the underlying multimap. 18030888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 18040888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>The returned multimap isn't threadsafe or serializable, even if 18050888a09821a98ac0680fad765217302858e70fa4Paul Duffin * {@code unfiltered} is. 18060888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 18070888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate 18080888a09821a98ac0680fad765217302858e70fa4Paul Duffin * across every key/value mapping in the underlying multimap and determine 18090888a09821a98ac0680fad765217302858e70fa4Paul Duffin * which satisfy the filter. When a live view is <i>not</i> needed, it may be 18100888a09821a98ac0680fad765217302858e70fa4Paul Duffin * faster to copy the filtered multimap and use the copy. 18110888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 18120888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>, 18130888a09821a98ac0680fad765217302858e70fa4Paul Duffin * as documented at {@link Predicate#apply}. Do not provide a predicate such 18140888a09821a98ac0680fad765217302858e70fa4Paul Duffin * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent 18150888a09821a98ac0680fad765217302858e70fa4Paul Duffin * with equals. 18160888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 18170888a09821a98ac0680fad765217302858e70fa4Paul Duffin * @since 14.0 18180888a09821a98ac0680fad765217302858e70fa4Paul Duffin */ 18190888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> SetMultimap<K, V> filterKeys( 18200888a09821a98ac0680fad765217302858e70fa4Paul Duffin SetMultimap<K, V> unfiltered, final Predicate<? super K> keyPredicate) { 18210888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (unfiltered instanceof FilteredKeySetMultimap) { 18220888a09821a98ac0680fad765217302858e70fa4Paul Duffin FilteredKeySetMultimap<K, V> prev = (FilteredKeySetMultimap<K, V>) unfiltered; 18230888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new FilteredKeySetMultimap<K, V>(prev.unfiltered(), 18240888a09821a98ac0680fad765217302858e70fa4Paul Duffin Predicates.and(prev.keyPredicate, keyPredicate)); 18250888a09821a98ac0680fad765217302858e70fa4Paul Duffin } else if (unfiltered instanceof FilteredSetMultimap) { 18260888a09821a98ac0680fad765217302858e70fa4Paul Duffin FilteredSetMultimap<K, V> prev = (FilteredSetMultimap<K, V>) unfiltered; 18270888a09821a98ac0680fad765217302858e70fa4Paul Duffin return filterFiltered(prev, Maps.<K>keyPredicateOnEntries(keyPredicate)); 18280888a09821a98ac0680fad765217302858e70fa4Paul Duffin } else { 18290888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new FilteredKeySetMultimap<K, V>(unfiltered, keyPredicate); 18300888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 18310888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 18320888a09821a98ac0680fad765217302858e70fa4Paul Duffin 18330888a09821a98ac0680fad765217302858e70fa4Paul Duffin /** 18340888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Returns a multimap containing the mappings in {@code unfiltered} whose keys 18350888a09821a98ac0680fad765217302858e70fa4Paul Duffin * satisfy a predicate. The returned multimap is a live view of 18360888a09821a98ac0680fad765217302858e70fa4Paul Duffin * {@code unfiltered}; changes to one affect the other. 18370888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 18380888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>The resulting multimap's views have iterators that don't support 18390888a09821a98ac0680fad765217302858e70fa4Paul Duffin * {@code remove()}, but all other methods are supported by the multimap and 18400888a09821a98ac0680fad765217302858e70fa4Paul Duffin * its views. When adding a key that doesn't satisfy the predicate, the 18410888a09821a98ac0680fad765217302858e70fa4Paul Duffin * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()} 18420888a09821a98ac0680fad765217302858e70fa4Paul Duffin * methods throw an {@link IllegalArgumentException}. 18430888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 18440888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>When methods such as {@code removeAll()} and {@code clear()} are called on 18450888a09821a98ac0680fad765217302858e70fa4Paul Duffin * the filtered multimap or its views, only mappings whose keys satisfy the 18460888a09821a98ac0680fad765217302858e70fa4Paul Duffin * filter will be removed from the underlying multimap. 18470888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 18480888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>The returned multimap isn't threadsafe or serializable, even if 18490888a09821a98ac0680fad765217302858e70fa4Paul Duffin * {@code unfiltered} is. 18500888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 18510888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate 18520888a09821a98ac0680fad765217302858e70fa4Paul Duffin * across every key/value mapping in the underlying multimap and determine 18530888a09821a98ac0680fad765217302858e70fa4Paul Duffin * which satisfy the filter. When a live view is <i>not</i> needed, it may be 18540888a09821a98ac0680fad765217302858e70fa4Paul Duffin * faster to copy the filtered multimap and use the copy. 18550888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 18560888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>, 18570888a09821a98ac0680fad765217302858e70fa4Paul Duffin * as documented at {@link Predicate#apply}. Do not provide a predicate such 18580888a09821a98ac0680fad765217302858e70fa4Paul Duffin * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent 18590888a09821a98ac0680fad765217302858e70fa4Paul Duffin * with equals. 18600888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 18610888a09821a98ac0680fad765217302858e70fa4Paul Duffin * @since 14.0 18620888a09821a98ac0680fad765217302858e70fa4Paul Duffin */ 18630888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> ListMultimap<K, V> filterKeys( 18640888a09821a98ac0680fad765217302858e70fa4Paul Duffin ListMultimap<K, V> unfiltered, final Predicate<? super K> keyPredicate) { 18650888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (unfiltered instanceof FilteredKeyListMultimap) { 18660888a09821a98ac0680fad765217302858e70fa4Paul Duffin FilteredKeyListMultimap<K, V> prev = (FilteredKeyListMultimap<K, V>) unfiltered; 18670888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new FilteredKeyListMultimap<K, V>(prev.unfiltered(), 18680888a09821a98ac0680fad765217302858e70fa4Paul Duffin Predicates.and(prev.keyPredicate, keyPredicate)); 18690888a09821a98ac0680fad765217302858e70fa4Paul Duffin } else { 18700888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new FilteredKeyListMultimap<K, V>(unfiltered, keyPredicate); 18710888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 18720888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 18731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 18751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a multimap containing the mappings in {@code unfiltered} whose values 18761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * satisfy a predicate. The returned multimap is a live view of 18771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code unfiltered}; changes to one affect the other. 18781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 18791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The resulting multimap's views have iterators that don't support 18801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code remove()}, but all other methods are supported by the multimap and 18811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * its views. When adding a value that doesn't satisfy the predicate, the 18827dd252788645e940eada959bdde927426e2531c9Paul Duffin * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()} 18837dd252788645e940eada959bdde927426e2531c9Paul Duffin * methods throw an {@link IllegalArgumentException}. 18841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 18851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When methods such as {@code removeAll()} and {@code clear()} are called on 18861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the filtered multimap or its views, only mappings whose value satisfy the 18871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * filter will be removed from the underlying multimap. 18881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 18891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap isn't threadsafe or serializable, even if 18901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code unfiltered} is. 18911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 18921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate 18931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * across every key/value mapping in the underlying multimap and determine 18941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * which satisfy the filter. When a live view is <i>not</i> needed, it may be 18951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * faster to copy the filtered multimap and use the copy. 18961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 18971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with 18981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * equals</i>, as documented at {@link Predicate#apply}. Do not provide a 18991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is 19001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * inconsistent with equals. 19011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 19021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 19031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 19040888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> Multimap<K, V> filterValues( 19050888a09821a98ac0680fad765217302858e70fa4Paul Duffin Multimap<K, V> unfiltered, final Predicate<? super V> valuePredicate) { 19060888a09821a98ac0680fad765217302858e70fa4Paul Duffin return filterEntries(unfiltered, Maps.<V>valuePredicateOnEntries(valuePredicate)); 19070888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 19080888a09821a98ac0680fad765217302858e70fa4Paul Duffin 19090888a09821a98ac0680fad765217302858e70fa4Paul Duffin /** 19100888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Returns a multimap containing the mappings in {@code unfiltered} whose values 19110888a09821a98ac0680fad765217302858e70fa4Paul Duffin * satisfy a predicate. The returned multimap is a live view of 19120888a09821a98ac0680fad765217302858e70fa4Paul Duffin * {@code unfiltered}; changes to one affect the other. 19130888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 19140888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>The resulting multimap's views have iterators that don't support 19150888a09821a98ac0680fad765217302858e70fa4Paul Duffin * {@code remove()}, but all other methods are supported by the multimap and 19160888a09821a98ac0680fad765217302858e70fa4Paul Duffin * its views. When adding a value that doesn't satisfy the predicate, the 19170888a09821a98ac0680fad765217302858e70fa4Paul Duffin * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()} 19180888a09821a98ac0680fad765217302858e70fa4Paul Duffin * methods throw an {@link IllegalArgumentException}. 19190888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 19200888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>When methods such as {@code removeAll()} and {@code clear()} are called on 19210888a09821a98ac0680fad765217302858e70fa4Paul Duffin * the filtered multimap or its views, only mappings whose value satisfy the 19220888a09821a98ac0680fad765217302858e70fa4Paul Duffin * filter will be removed from the underlying multimap. 19230888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 19240888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>The returned multimap isn't threadsafe or serializable, even if 19250888a09821a98ac0680fad765217302858e70fa4Paul Duffin * {@code unfiltered} is. 19260888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 19270888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate 19280888a09821a98ac0680fad765217302858e70fa4Paul Duffin * across every key/value mapping in the underlying multimap and determine 19290888a09821a98ac0680fad765217302858e70fa4Paul Duffin * which satisfy the filter. When a live view is <i>not</i> needed, it may be 19300888a09821a98ac0680fad765217302858e70fa4Paul Duffin * faster to copy the filtered multimap and use the copy. 19310888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 19320888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with 19330888a09821a98ac0680fad765217302858e70fa4Paul Duffin * equals</i>, as documented at {@link Predicate#apply}. Do not provide a 19340888a09821a98ac0680fad765217302858e70fa4Paul Duffin * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is 19350888a09821a98ac0680fad765217302858e70fa4Paul Duffin * inconsistent with equals. 19360888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 19370888a09821a98ac0680fad765217302858e70fa4Paul Duffin * @since 14.0 19380888a09821a98ac0680fad765217302858e70fa4Paul Duffin */ 19390888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> SetMultimap<K, V> filterValues( 19400888a09821a98ac0680fad765217302858e70fa4Paul Duffin SetMultimap<K, V> unfiltered, final Predicate<? super V> valuePredicate) { 19410888a09821a98ac0680fad765217302858e70fa4Paul Duffin return filterEntries(unfiltered, Maps.<V>valuePredicateOnEntries(valuePredicate)); 19421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 19451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a multimap containing the mappings in {@code unfiltered} that 19461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * satisfy a predicate. The returned multimap is a live view of 19471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code unfiltered}; changes to one affect the other. 19481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 19491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The resulting multimap's views have iterators that don't support 19501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code remove()}, but all other methods are supported by the multimap and 19511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * its views. When adding a key/value pair that doesn't satisfy the predicate, 19527dd252788645e940eada959bdde927426e2531c9Paul Duffin * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()} 19537dd252788645e940eada959bdde927426e2531c9Paul Duffin * methods throw an {@link IllegalArgumentException}. 19541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 19551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When methods such as {@code removeAll()} and {@code clear()} are called on 19561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the filtered multimap or its views, only mappings whose keys satisfy the 19571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * filter will be removed from the underlying multimap. 19581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 19591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap isn't threadsafe or serializable, even if 19601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code unfiltered} is. 19611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 19621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate 19631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * across every key/value mapping in the underlying multimap and determine 19641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * which satisfy the filter. When a live view is <i>not</i> needed, it may be 19651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * faster to copy the filtered multimap and use the copy. 19661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 19671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with 19681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * equals</i>, as documented at {@link Predicate#apply}. 19691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 19701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 19711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 19720888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> Multimap<K, V> filterEntries( 19730888a09821a98ac0680fad765217302858e70fa4Paul Duffin Multimap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) { 19741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(entryPredicate); 19750888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (unfiltered instanceof SetMultimap) { 19760888a09821a98ac0680fad765217302858e70fa4Paul Duffin return filterEntries((SetMultimap<K, V>) unfiltered, entryPredicate); 19770888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 19780888a09821a98ac0680fad765217302858e70fa4Paul Duffin return (unfiltered instanceof FilteredMultimap) 19790888a09821a98ac0680fad765217302858e70fa4Paul Duffin ? filterFiltered((FilteredMultimap<K, V>) unfiltered, entryPredicate) 19800888a09821a98ac0680fad765217302858e70fa4Paul Duffin : new FilteredEntryMultimap<K, V>(checkNotNull(unfiltered), entryPredicate); 19810888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 19820888a09821a98ac0680fad765217302858e70fa4Paul Duffin 19830888a09821a98ac0680fad765217302858e70fa4Paul Duffin /** 19840888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Returns a multimap containing the mappings in {@code unfiltered} that 19850888a09821a98ac0680fad765217302858e70fa4Paul Duffin * satisfy a predicate. The returned multimap is a live view of 19860888a09821a98ac0680fad765217302858e70fa4Paul Duffin * {@code unfiltered}; changes to one affect the other. 19870888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 19880888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>The resulting multimap's views have iterators that don't support 19890888a09821a98ac0680fad765217302858e70fa4Paul Duffin * {@code remove()}, but all other methods are supported by the multimap and 19900888a09821a98ac0680fad765217302858e70fa4Paul Duffin * its views. When adding a key/value pair that doesn't satisfy the predicate, 19910888a09821a98ac0680fad765217302858e70fa4Paul Duffin * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()} 19920888a09821a98ac0680fad765217302858e70fa4Paul Duffin * methods throw an {@link IllegalArgumentException}. 19930888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 19940888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>When methods such as {@code removeAll()} and {@code clear()} are called on 19950888a09821a98ac0680fad765217302858e70fa4Paul Duffin * the filtered multimap or its views, only mappings whose keys satisfy the 19960888a09821a98ac0680fad765217302858e70fa4Paul Duffin * filter will be removed from the underlying multimap. 19970888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 19980888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>The returned multimap isn't threadsafe or serializable, even if 19990888a09821a98ac0680fad765217302858e70fa4Paul Duffin * {@code unfiltered} is. 20000888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 20010888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate 20020888a09821a98ac0680fad765217302858e70fa4Paul Duffin * across every key/value mapping in the underlying multimap and determine 20030888a09821a98ac0680fad765217302858e70fa4Paul Duffin * which satisfy the filter. When a live view is <i>not</i> needed, it may be 20040888a09821a98ac0680fad765217302858e70fa4Paul Duffin * faster to copy the filtered multimap and use the copy. 20050888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 20060888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with 20070888a09821a98ac0680fad765217302858e70fa4Paul Duffin * equals</i>, as documented at {@link Predicate#apply}. 20080888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 20090888a09821a98ac0680fad765217302858e70fa4Paul Duffin * @since 14.0 20100888a09821a98ac0680fad765217302858e70fa4Paul Duffin */ 20110888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <K, V> SetMultimap<K, V> filterEntries( 20120888a09821a98ac0680fad765217302858e70fa4Paul Duffin SetMultimap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) { 20130888a09821a98ac0680fad765217302858e70fa4Paul Duffin checkNotNull(entryPredicate); 20140888a09821a98ac0680fad765217302858e70fa4Paul Duffin return (unfiltered instanceof FilteredSetMultimap) 20150888a09821a98ac0680fad765217302858e70fa4Paul Duffin ? filterFiltered((FilteredSetMultimap<K, V>) unfiltered, entryPredicate) 20160888a09821a98ac0680fad765217302858e70fa4Paul Duffin : new FilteredEntrySetMultimap<K, V>(checkNotNull(unfiltered), entryPredicate); 20171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 20201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Support removal operations when filtering a filtered multimap. Since a 20211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * filtered multimap has iterators that don't support remove, passing one to 20227dd252788645e940eada959bdde927426e2531c9Paul Duffin * the FilteredEntryMultimap constructor would lead to a multimap whose removal 20231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * operations would fail. This method combines the predicates to avoid that 20241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * problem. 20251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 20267dd252788645e940eada959bdde927426e2531c9Paul Duffin private static <K, V> Multimap<K, V> filterFiltered(FilteredMultimap<K, V> multimap, 20271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Predicate<? super Entry<K, V>> entryPredicate) { 20280888a09821a98ac0680fad765217302858e70fa4Paul Duffin Predicate<Entry<K, V>> predicate 20290888a09821a98ac0680fad765217302858e70fa4Paul Duffin = Predicates.and(multimap.entryPredicate(), entryPredicate); 20300888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new FilteredEntryMultimap<K, V>(multimap.unfiltered(), predicate); 20310888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 20320888a09821a98ac0680fad765217302858e70fa4Paul Duffin 20330888a09821a98ac0680fad765217302858e70fa4Paul Duffin /** 20340888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Support removal operations when filtering a filtered multimap. Since a filtered multimap has 20350888a09821a98ac0680fad765217302858e70fa4Paul Duffin * iterators that don't support remove, passing one to the FilteredEntryMultimap constructor would 20360888a09821a98ac0680fad765217302858e70fa4Paul Duffin * lead to a multimap whose removal operations would fail. This method combines the predicates to 20370888a09821a98ac0680fad765217302858e70fa4Paul Duffin * avoid that problem. 20380888a09821a98ac0680fad765217302858e70fa4Paul Duffin */ 20390888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static <K, V> SetMultimap<K, V> filterFiltered( 20400888a09821a98ac0680fad765217302858e70fa4Paul Duffin FilteredSetMultimap<K, V> multimap, 20410888a09821a98ac0680fad765217302858e70fa4Paul Duffin Predicate<? super Entry<K, V>> entryPredicate) { 20420888a09821a98ac0680fad765217302858e70fa4Paul Duffin Predicate<Entry<K, V>> predicate 20430888a09821a98ac0680fad765217302858e70fa4Paul Duffin = Predicates.and(multimap.entryPredicate(), entryPredicate); 20440888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new FilteredEntrySetMultimap<K, V>(multimap.unfiltered(), predicate); 20450888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 20460888a09821a98ac0680fad765217302858e70fa4Paul Duffin 20470888a09821a98ac0680fad765217302858e70fa4Paul Duffin static boolean equalsImpl(Multimap<?, ?> multimap, @Nullable Object object) { 20480888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (object == multimap) { 20490888a09821a98ac0680fad765217302858e70fa4Paul Duffin return true; 20500888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 20510888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (object instanceof Multimap) { 20520888a09821a98ac0680fad765217302858e70fa4Paul Duffin Multimap<?, ?> that = (Multimap<?, ?>) object; 20530888a09821a98ac0680fad765217302858e70fa4Paul Duffin return multimap.asMap().equals(that.asMap()); 20540888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 20550888a09821a98ac0680fad765217302858e70fa4Paul Duffin return false; 20561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20580888a09821a98ac0680fad765217302858e70fa4Paul Duffin // TODO(jlevy): Create methods that filter a SortedSetMultimap. 20591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 2060