Home | History | Annotate | Download | only in collect
      1 /*
      2  * Copyright (C) 2007 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.common.collect;
     18 
     19 import com.google.common.annotations.GwtCompatible;
     20 import com.google.common.base.Function;
     21 import com.google.common.base.Joiner;
     22 import com.google.common.base.Joiner.MapJoiner;
     23 import com.google.common.base.Preconditions;
     24 import static com.google.common.base.Preconditions.checkNotNull;
     25 import static com.google.common.base.Preconditions.checkState;
     26 import com.google.common.base.Supplier;
     27 
     28 import java.io.IOException;
     29 import java.io.ObjectInputStream;
     30 import java.io.ObjectOutputStream;
     31 import java.io.Serializable;
     32 import java.util.AbstractSet;
     33 import java.util.Collection;
     34 import java.util.Collections;
     35 import java.util.Comparator;
     36 import java.util.HashSet;
     37 import java.util.Iterator;
     38 import java.util.List;
     39 import java.util.Map;
     40 import java.util.Map.Entry;
     41 import java.util.NoSuchElementException;
     42 import java.util.Set;
     43 import java.util.SortedSet;
     44 
     45 import javax.annotation.Nullable;
     46 
     47 /**
     48  * Provides static methods acting on or generating a {@code Multimap}.
     49  *
     50  * @author Jared Levy
     51  * @author Robert Konigsberg
     52  * @author Mike Bostock
     53  * @since 2010.01.04 <b>stable</b> (imported from Google Collections Library)
     54  */
     55 @GwtCompatible
     56 public final class Multimaps {
     57   private Multimaps() {}
     58 
     59   /**
     60    * Creates a new {@code Multimap} that uses the provided map and factory. It
     61    * can generate a multimap based on arbitrary {@link Map} and
     62    * {@link Collection} classes.
     63    *
     64    * <p>The {@code factory}-generated and {@code map} classes determine the
     65    * multimap iteration order. They also specify the behavior of the
     66    * {@code equals}, {@code hashCode}, and {@code toString} methods for the
     67    * multimap and its returned views. However, the multimap's {@code get}
     68    * method returns instances of a different class than {@code factory.get()}
     69    * does.
     70    *
     71    * <p>The multimap is serializable if {@code map}, {@code factory}, the
     72    * collections generated by {@code factory}, and the multimap contents are all
     73    * serializable.
     74    *
     75    * <p>The multimap is not threadsafe when any concurrent operations update the
     76    * multimap, even if {@code map} and the instances generated by
     77    * {@code factory} are. Concurrent read operations will work correctly. To
     78    * allow concurrent update operations, wrap the multimap with a call to
     79    * {@link #synchronizedMultimap}.
     80    *
     81    * <p>Call this method only when the simpler methods
     82    * {@link ArrayListMultimap#create()}, {@link HashMultimap#create()},
     83    * {@link LinkedHashMultimap#create()}, {@link LinkedListMultimap#create()},
     84    * {@link TreeMultimap#create()}, and
     85    * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice.
     86    *
     87    * <p>Note: the multimap assumes complete ownership over of {@code map} and
     88    * the collections returned by {@code factory}. Those objects should not be
     89    * manually updated and they should not use soft, weak, or phantom references.
     90    *
     91    * @param map place to store the mapping from each key to its corresponding
     92    *     values
     93    * @param factory supplier of new, empty collections that will each hold all
     94    *     values for a given key
     95    * @throws IllegalArgumentException if {@code map} is not empty
     96    */
     97   public static <K, V> Multimap<K, V> newMultimap(Map<K, Collection<V>> map,
     98       final Supplier<? extends Collection<V>> factory) {
     99     return new CustomMultimap<K, V>(map, factory);
    100   }
    101 
    102   private static class CustomMultimap<K, V> extends AbstractMultimap<K, V> {
    103     transient Supplier<? extends Collection<V>> factory;
    104 
    105     CustomMultimap(Map<K, Collection<V>> map,
    106         Supplier<? extends Collection<V>> factory) {
    107       super(map);
    108       this.factory = checkNotNull(factory);
    109     }
    110 
    111     @Override protected Collection<V> createCollection() {
    112       return factory.get();
    113     }
    114 
    115     // can't use Serialization writeMultimap and populateMultimap methods since
    116     // there's no way to generate the empty backing map.
    117 
    118     /** @serialData the factory and the backing map */
    119     private void writeObject(ObjectOutputStream stream) throws IOException {
    120       stream.defaultWriteObject();
    121       stream.writeObject(factory);
    122       stream.writeObject(backingMap());
    123     }
    124 
    125     @SuppressWarnings("unchecked") // reading data stored by writeObject
    126     private void readObject(ObjectInputStream stream)
    127         throws IOException, ClassNotFoundException {
    128       stream.defaultReadObject();
    129       factory = (Supplier<? extends Collection<V>>) stream.readObject();
    130       Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
    131       setMap(map);
    132     }
    133 
    134     private static final long serialVersionUID = 0;
    135   }
    136 
    137   /**
    138    * Creates a new {@code ListMultimap} that uses the provided map and factory.
    139    * It can generate a multimap based on arbitrary {@link Map} and {@link List}
    140    * classes.
    141    *
    142    * <p>The {@code factory}-generated and {@code map} classes determine the
    143    * multimap iteration order. They also specify the behavior of the
    144    * {@code equals}, {@code hashCode}, and {@code toString} methods for the
    145    * multimap and its returned views. The multimap's {@code get}, {@code
    146    * removeAll}, and {@code replaceValues} methods return {@code RandomAccess}
    147    * lists if the factory does. However, the multimap's {@code get} method
    148    * returns instances of a different class than does {@code factory.get()}.
    149    *
    150    * <p>The multimap is serializable if {@code map}, {@code factory}, the
    151    * lists generated by {@code factory}, and the multimap contents are all
    152    * serializable.
    153    *
    154    * <p>The multimap is not threadsafe when any concurrent operations update the
    155    * multimap, even if {@code map} and the instances generated by
    156    * {@code factory} are. Concurrent read operations will work correctly. To
    157    * allow concurrent update operations, wrap the multimap with a call to
    158    * {@link #synchronizedListMultimap}.
    159    *
    160    * <p>Call this method only when the simpler methods
    161    * {@link ArrayListMultimap#create()} and {@link LinkedListMultimap#create()}
    162    * won't suffice.
    163    *
    164    * <p>Note: the multimap assumes complete ownership over of {@code map} and
    165    * the lists returned by {@code factory}. Those objects should not be manually
    166    * updated and they should not use soft, weak, or phantom references.
    167    *
    168    * @param map place to store the mapping from each key to its corresponding
    169    *     values
    170    * @param factory supplier of new, empty lists that will each hold all values
    171    *     for a given key
    172    * @throws IllegalArgumentException if {@code map} is not empty
    173    */
    174   public static <K, V> ListMultimap<K, V> newListMultimap(
    175       Map<K, Collection<V>> map, final Supplier<? extends List<V>> factory) {
    176     return new CustomListMultimap<K, V>(map, factory);
    177   }
    178 
    179   private static class CustomListMultimap<K, V>
    180       extends AbstractListMultimap<K, V> {
    181     transient Supplier<? extends List<V>> factory;
    182 
    183     CustomListMultimap(Map<K, Collection<V>> map,
    184         Supplier<? extends List<V>> factory) {
    185       super(map);
    186       this.factory = checkNotNull(factory);
    187     }
    188 
    189     @Override protected List<V> createCollection() {
    190       return factory.get();
    191     }
    192 
    193     /** @serialData the factory and the backing map */
    194     private void writeObject(ObjectOutputStream stream) throws IOException {
    195       stream.defaultWriteObject();
    196       stream.writeObject(factory);
    197       stream.writeObject(backingMap());
    198     }
    199 
    200     @SuppressWarnings("unchecked") // reading data stored by writeObject
    201     private void readObject(ObjectInputStream stream)
    202         throws IOException, ClassNotFoundException {
    203       stream.defaultReadObject();
    204       factory = (Supplier<? extends List<V>>) stream.readObject();
    205       Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
    206       setMap(map);
    207     }
    208 
    209     private static final long serialVersionUID = 0;
    210   }
    211 
    212   /**
    213    * Creates a new {@code SetMultimap} that uses the provided map and factory.
    214    * It can generate a multimap based on arbitrary {@link Map} and {@link Set}
    215    * classes.
    216    *
    217    * <p>The {@code factory}-generated and {@code map} classes determine the
    218    * multimap iteration order. They also specify the behavior of the
    219    * {@code equals}, {@code hashCode}, and {@code toString} methods for the
    220    * multimap and its returned views. However, the multimap's {@code get}
    221    * method returns instances of a different class than {@code factory.get()}
    222    * does.
    223    *
    224    * <p>The multimap is serializable if {@code map}, {@code factory}, the
    225    * sets generated by {@code factory}, and the multimap contents are all
    226    * serializable.
    227    *
    228    * <p>The multimap is not threadsafe when any concurrent operations update the
    229    * multimap, even if {@code map} and the instances generated by
    230    * {@code factory} are. Concurrent read operations will work correctly. To
    231    * allow concurrent update operations, wrap the multimap with a call to
    232    * {@link #synchronizedSetMultimap}.
    233    *
    234    * <p>Call this method only when the simpler methods
    235    * {@link HashMultimap#create()}, {@link LinkedHashMultimap#create()},
    236    * {@link TreeMultimap#create()}, and
    237    * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice.
    238    *
    239    * <p>Note: the multimap assumes complete ownership over of {@code map} and
    240    * the sets returned by {@code factory}. Those objects should not be manually
    241    * updated and they should not use soft, weak, or phantom references.
    242    *
    243    * @param map place to store the mapping from each key to its corresponding
    244    *     values
    245    * @param factory supplier of new, empty sets that will each hold all values
    246    *     for a given key
    247    * @throws IllegalArgumentException if {@code map} is not empty
    248    */
    249   public static <K, V> SetMultimap<K, V> newSetMultimap(
    250       Map<K, Collection<V>> map, final Supplier<? extends Set<V>> factory) {
    251     return new CustomSetMultimap<K, V>(map, factory);
    252   }
    253 
    254   private static class CustomSetMultimap<K, V>
    255       extends AbstractSetMultimap<K, V> {
    256     transient Supplier<? extends Set<V>> factory;
    257 
    258     CustomSetMultimap(Map<K, Collection<V>> map,
    259         Supplier<? extends Set<V>> factory) {
    260       super(map);
    261       this.factory = checkNotNull(factory);
    262     }
    263 
    264     @Override protected Set<V> createCollection() {
    265       return factory.get();
    266     }
    267 
    268     /** @serialData the factory and the backing map */
    269     private void writeObject(ObjectOutputStream stream) throws IOException {
    270       stream.defaultWriteObject();
    271       stream.writeObject(factory);
    272       stream.writeObject(backingMap());
    273     }
    274 
    275     @SuppressWarnings("unchecked") // reading data stored by writeObject
    276     private void readObject(ObjectInputStream stream)
    277         throws IOException, ClassNotFoundException {
    278       stream.defaultReadObject();
    279       factory = (Supplier<? extends Set<V>>) stream.readObject();
    280       Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
    281       setMap(map);
    282     }
    283 
    284     private static final long serialVersionUID = 0;
    285   }
    286 
    287   /**
    288    * Creates a new {@code SortedSetMultimap} that uses the provided map and
    289    * factory. It can generate a multimap based on arbitrary {@link Map} and
    290    * {@link SortedSet} classes.
    291    *
    292    * <p>The {@code factory}-generated and {@code map} classes determine the
    293    * multimap iteration order. They also specify the behavior of the
    294    * {@code equals}, {@code hashCode}, and {@code toString} methods for the
    295    * multimap and its returned views. However, the multimap's {@code get}
    296    * method returns instances of a different class than {@code factory.get()}
    297    * does.
    298    *
    299    * <p>The multimap is serializable if {@code map}, {@code factory}, the
    300    * sets generated by {@code factory}, and the multimap contents are all
    301    * serializable.
    302    *
    303    * <p>The multimap is not threadsafe when any concurrent operations update the
    304    * multimap, even if {@code map} and the instances generated by
    305    * {@code factory} are. Concurrent read operations will work correctly. To
    306    * allow concurrent update operations, wrap the multimap with a call to
    307    * {@link #synchronizedSortedSetMultimap}.
    308    *
    309    * <p>Call this method only when the simpler methods
    310    * {@link TreeMultimap#create()} and
    311    * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice.
    312    *
    313    * <p>Note: the multimap assumes complete ownership over of {@code map} and
    314    * the sets returned by {@code factory}. Those objects should not be manually
    315    * updated and they should not use soft, weak, or phantom references.
    316    *
    317    * @param map place to store the mapping from each key to its corresponding
    318    *     values
    319    * @param factory supplier of new, empty sorted sets that will each hold
    320    *     all values for a given key
    321    * @throws IllegalArgumentException if {@code map} is not empty
    322    */
    323   public static <K, V> SortedSetMultimap<K, V> newSortedSetMultimap(
    324       Map<K, Collection<V>> map,
    325       final Supplier<? extends SortedSet<V>> factory) {
    326     return new CustomSortedSetMultimap<K, V>(map, factory);
    327   }
    328 
    329   private static class CustomSortedSetMultimap<K, V>
    330       extends AbstractSortedSetMultimap<K, V> {
    331     transient Supplier<? extends SortedSet<V>> factory;
    332     transient Comparator<? super V> valueComparator;
    333 
    334     CustomSortedSetMultimap(Map<K, Collection<V>> map,
    335         Supplier<? extends SortedSet<V>> factory) {
    336       super(map);
    337       this.factory = checkNotNull(factory);
    338       valueComparator = factory.get().comparator();
    339     }
    340 
    341     @Override protected SortedSet<V> createCollection() {
    342       return factory.get();
    343     }
    344 
    345     /*@Override*/ public Comparator<? super V> valueComparator() {
    346       return valueComparator;
    347     }
    348 
    349     /** @serialData the factory and the backing map */
    350     private void writeObject(ObjectOutputStream stream) throws IOException {
    351       stream.defaultWriteObject();
    352       stream.writeObject(factory);
    353       stream.writeObject(backingMap());
    354     }
    355 
    356     @SuppressWarnings("unchecked") // reading data stored by writeObject
    357     private void readObject(ObjectInputStream stream)
    358         throws IOException, ClassNotFoundException {
    359       stream.defaultReadObject();
    360       factory = (Supplier<? extends SortedSet<V>>) stream.readObject();
    361       valueComparator = factory.get().comparator();
    362       Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
    363       setMap(map);
    364     }
    365 
    366     private static final long serialVersionUID = 0;
    367   }
    368 
    369   /**
    370    * Copies each key-value mapping in {@code source} into {@code dest}, with
    371    * its key and value reversed.
    372    *
    373    * @param source any multimap
    374    * @param dest the multimap to copy into; usually empty
    375    * @return {@code dest}
    376    */
    377   public static <K, V, M extends Multimap<K, V>> M invertFrom(
    378       Multimap<? extends V, ? extends K> source, M dest) {
    379     for (Map.Entry<? extends V, ? extends K> entry : source.entries()) {
    380       dest.put(entry.getValue(), entry.getKey());
    381     }
    382     return dest;
    383   }
    384 
    385   /**
    386    * Returns a synchronized (thread-safe) multimap backed by the specified
    387    * multimap. In order to guarantee serial access, it is critical that
    388    * <b>all</b> access to the backing multimap is accomplished through the
    389    * returned multimap.
    390    *
    391    * <p>It is imperative that the user manually synchronize on the returned
    392    * multimap when accessing any of its collection views: <pre>  {@code
    393    *
    394    *  Multimap<K, V> m = Multimaps.synchronizedMultimap(
    395    *      HashMultimap.<K, V>create());
    396    *  ...
    397    *  Set<K> s = m.keySet();  // Needn't be in synchronized block
    398    *  ...
    399    *  synchronized (m) {  // Synchronizing on m, not s!
    400    *    Iterator<K> i = s.iterator(); // Must be in synchronized block
    401    *    while (i.hasNext()) {
    402    *      foo(i.next());
    403    *    }
    404    *  }}</pre>
    405    *
    406    * Failure to follow this advice may result in non-deterministic behavior.
    407    *
    408    * <p>Note that the generated multimap's {@link Multimap#removeAll} and
    409    * {@link Multimap#replaceValues} methods return collections that aren't
    410    * synchronized.
    411    *
    412    * <p>The returned multimap will be serializable if the specified multimap is
    413    * serializable.
    414    *
    415    * @param multimap the multimap to be wrapped in a synchronized view
    416    * @return a synchronized view of the specified multimap
    417    */
    418   public static <K, V> Multimap<K, V> synchronizedMultimap(
    419       Multimap<K, V> multimap) {
    420     return Synchronized.multimap(multimap, null);
    421   }
    422 
    423   /**
    424    * Returns an unmodifiable view of the specified multimap. Query operations on
    425    * the returned multimap "read through" to the specified multimap, and
    426    * attempts to modify the returned multimap, either directly or through the
    427    * multimap's views, result in an {@code UnsupportedOperationException}.
    428    *
    429    * <p>Note that the generated multimap's {@link Multimap#removeAll} and
    430    * {@link Multimap#replaceValues} methods return collections that are
    431    * modifiable.
    432    *
    433    * <p>The returned multimap will be serializable if the specified multimap is
    434    * serializable.
    435    *
    436    * @param delegate the multimap for which an unmodifiable view is to be
    437    *     returned
    438    * @return an unmodifiable view of the specified multimap
    439    */
    440   public static <K, V> Multimap<K, V> unmodifiableMultimap(
    441       Multimap<K, V> delegate) {
    442     return new UnmodifiableMultimap<K, V>(delegate);
    443   }
    444 
    445   private static class UnmodifiableMultimap<K, V>
    446       extends ForwardingMultimap<K, V> implements Serializable {
    447     final Multimap<K, V> delegate;
    448     transient Collection<Entry<K, V>> entries;
    449     transient Multiset<K> keys;
    450     transient Set<K> keySet;
    451     transient Collection<V> values;
    452     transient Map<K, Collection<V>> map;
    453 
    454     UnmodifiableMultimap(final Multimap<K, V> delegate) {
    455       this.delegate = delegate;
    456     }
    457 
    458     @Override protected Multimap<K, V> delegate() {
    459       return delegate;
    460     }
    461 
    462     @Override public void clear() {
    463       throw new UnsupportedOperationException();
    464     }
    465 
    466     @Override public Map<K, Collection<V>> asMap() {
    467       Map<K, Collection<V>> result = map;
    468       if (result == null) {
    469         final Map<K, Collection<V>> unmodifiableMap
    470             = Collections.unmodifiableMap(delegate.asMap());
    471         map = result = new ForwardingMap<K, Collection<V>>() {
    472           @Override protected Map<K, Collection<V>> delegate() {
    473             return unmodifiableMap;
    474           }
    475 
    476           Set<Entry<K, Collection<V>>> entrySet;
    477 
    478           @Override public Set<Map.Entry<K, Collection<V>>> entrySet() {
    479             Set<Entry<K, Collection<V>>> result = entrySet;
    480             return (result == null)
    481                 ? entrySet
    482                     = unmodifiableAsMapEntries(unmodifiableMap.entrySet())
    483                 : result;
    484           }
    485 
    486           @Override public Collection<V> get(Object key) {
    487             Collection<V> collection = unmodifiableMap.get(key);
    488             return (collection == null)
    489                 ? null : unmodifiableValueCollection(collection);
    490           }
    491 
    492           Collection<Collection<V>> asMapValues;
    493 
    494           @Override public Collection<Collection<V>> values() {
    495             Collection<Collection<V>> result = asMapValues;
    496             return (result == null)
    497                 ? asMapValues
    498                     = new UnmodifiableAsMapValues<V>(unmodifiableMap.values())
    499                 : result;
    500           }
    501 
    502           @Override public boolean containsValue(Object o) {
    503             return values().contains(o);
    504           }
    505         };
    506       }
    507       return result;
    508     }
    509 
    510     @Override public Collection<Entry<K, V>> entries() {
    511       Collection<Entry<K, V>> result = entries;
    512       if (result == null) {
    513         entries = result = unmodifiableEntries(delegate.entries());
    514       }
    515       return result;
    516     }
    517 
    518     @Override public Collection<V> get(K key) {
    519       return unmodifiableValueCollection(delegate.get(key));
    520     }
    521 
    522     @Override public Multiset<K> keys() {
    523       Multiset<K> result = keys;
    524       if (result == null) {
    525         keys = result = Multisets.unmodifiableMultiset(delegate.keys());
    526       }
    527       return result;
    528     }
    529 
    530     @Override public Set<K> keySet() {
    531       Set<K> result = keySet;
    532       if (result == null) {
    533         keySet = result = Collections.unmodifiableSet(delegate.keySet());
    534       }
    535       return result;
    536     }
    537 
    538     @Override public boolean put(K key, V value) {
    539       throw new UnsupportedOperationException();
    540     }
    541 
    542     @Override public boolean putAll(K key,
    543         @SuppressWarnings("hiding") Iterable<? extends V> values) {
    544       throw new UnsupportedOperationException();
    545     }
    546 
    547     @Override
    548     public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
    549       throw new UnsupportedOperationException();
    550     }
    551 
    552     @Override public boolean remove(Object key, Object value) {
    553       throw new UnsupportedOperationException();
    554     }
    555 
    556     @Override public Collection<V> removeAll(Object key) {
    557       throw new UnsupportedOperationException();
    558     }
    559 
    560     @Override public Collection<V> replaceValues(K key,
    561         @SuppressWarnings("hiding") Iterable<? extends V> values) {
    562       throw new UnsupportedOperationException();
    563     }
    564 
    565     @Override public Collection<V> values() {
    566       Collection<V> result = values;
    567       if (result == null) {
    568         values = result = Collections.unmodifiableCollection(delegate.values());
    569       }
    570       return result;
    571     }
    572 
    573     private static final long serialVersionUID = 0;
    574   }
    575 
    576   private static class UnmodifiableAsMapValues<V>
    577       extends ForwardingCollection<Collection<V>> {
    578     final Collection<Collection<V>> delegate;
    579     UnmodifiableAsMapValues(Collection<Collection<V>> delegate) {
    580       this.delegate = Collections.unmodifiableCollection(delegate);
    581     }
    582     @Override protected Collection<Collection<V>> delegate() {
    583       return delegate;
    584     }
    585     @Override public Iterator<Collection<V>> iterator() {
    586       final Iterator<Collection<V>> iterator = delegate.iterator();
    587       return new Iterator<Collection<V>>() {
    588         public boolean hasNext() {
    589           return iterator.hasNext();
    590         }
    591         public Collection<V> next() {
    592           return unmodifiableValueCollection(iterator.next());
    593         }
    594         public void remove() {
    595           throw new UnsupportedOperationException();
    596         }
    597       };
    598     }
    599     @Override public Object[] toArray() {
    600       return ObjectArrays.toArrayImpl(this);
    601     }
    602     @Override public <T> T[] toArray(T[] array) {
    603       return ObjectArrays.toArrayImpl(this, array);
    604     }
    605     @Override public boolean contains(Object o) {
    606       return Iterators.contains(iterator(), o);
    607     }
    608     @Override public boolean containsAll(Collection<?> c) {
    609       return Collections2.containsAll(this, c);
    610     }
    611   }
    612 
    613   private static class UnmodifiableListMultimap<K, V>
    614       extends UnmodifiableMultimap<K, V> implements ListMultimap<K, V> {
    615     UnmodifiableListMultimap(ListMultimap<K, V> delegate) {
    616       super(delegate);
    617     }
    618     @Override public ListMultimap<K, V> delegate() {
    619       return (ListMultimap<K, V>) super.delegate();
    620     }
    621     @Override public List<V> get(K key) {
    622       return Collections.unmodifiableList(delegate().get(key));
    623     }
    624     @Override public List<V> removeAll(Object key) {
    625       throw new UnsupportedOperationException();
    626     }
    627     @Override public List<V> replaceValues(
    628         K key, @SuppressWarnings("hiding") Iterable<? extends V> values) {
    629       throw new UnsupportedOperationException();
    630     }
    631     private static final long serialVersionUID = 0;
    632   }
    633 
    634   private static class UnmodifiableSetMultimap<K, V>
    635       extends UnmodifiableMultimap<K, V> implements SetMultimap<K, V> {
    636     UnmodifiableSetMultimap(SetMultimap<K, V> delegate) {
    637       super(delegate);
    638     }
    639     @Override public SetMultimap<K, V> delegate() {
    640       return (SetMultimap<K, V>) super.delegate();
    641     }
    642     @Override public Set<V> get(K key) {
    643       /*
    644        * Note that this doesn't return a SortedSet when delegate is a
    645        * SortedSetMultiset, unlike (SortedSet<V>) super.get().
    646        */
    647       return Collections.unmodifiableSet(delegate().get(key));
    648     }
    649     @Override public Set<Map.Entry<K, V>> entries() {
    650       return Maps.unmodifiableEntrySet(delegate().entries());
    651     }
    652     @Override public Set<V> removeAll(Object key) {
    653       throw new UnsupportedOperationException();
    654     }
    655     @Override public Set<V> replaceValues(
    656         K key, @SuppressWarnings("hiding") Iterable<? extends V> values) {
    657       throw new UnsupportedOperationException();
    658     }
    659     private static final long serialVersionUID = 0;
    660   }
    661 
    662   private static class UnmodifiableSortedSetMultimap<K, V>
    663       extends UnmodifiableSetMultimap<K, V> implements SortedSetMultimap<K, V> {
    664     UnmodifiableSortedSetMultimap(SortedSetMultimap<K, V> delegate) {
    665       super(delegate);
    666     }
    667     @Override public SortedSetMultimap<K, V> delegate() {
    668       return (SortedSetMultimap<K, V>) super.delegate();
    669     }
    670     @Override public SortedSet<V> get(K key) {
    671       return Collections.unmodifiableSortedSet(delegate().get(key));
    672     }
    673     @Override public SortedSet<V> removeAll(Object key) {
    674       throw new UnsupportedOperationException();
    675     }
    676     @Override public SortedSet<V> replaceValues(
    677         K key, @SuppressWarnings("hiding") Iterable<? extends V> values) {
    678       throw new UnsupportedOperationException();
    679     }
    680     public Comparator<? super V> valueComparator() {
    681       return delegate().valueComparator();
    682     }
    683     private static final long serialVersionUID = 0;
    684   }
    685 
    686   /**
    687    * Returns a synchronized (thread-safe) {@code SetMultimap} backed by the
    688    * specified multimap.
    689    *
    690    * <p>You must follow the warnings described in {@link #synchronizedMultimap}.
    691    *
    692    * <p>The returned multimap will be serializable if the specified multimap is
    693    * serializable.
    694    *
    695    * @param multimap the multimap to be wrapped
    696    * @return a synchronized view of the specified multimap
    697    */
    698   public static <K, V> SetMultimap<K, V> synchronizedSetMultimap(
    699       SetMultimap<K, V> multimap) {
    700     return Synchronized.setMultimap(multimap, null);
    701   }
    702 
    703   /**
    704    * Returns an unmodifiable view of the specified {@code SetMultimap}. Query
    705    * operations on the returned multimap "read through" to the specified
    706    * multimap, and attempts to modify the returned multimap, either directly or
    707    * through the multimap's views, result in an
    708    * {@code UnsupportedOperationException}.
    709    *
    710    * <p>Note that the generated multimap's {@link Multimap#removeAll} and
    711    * {@link Multimap#replaceValues} methods return collections that are
    712    * modifiable.
    713    *
    714    * <p>The returned multimap will be serializable if the specified multimap is
    715    * serializable.
    716    *
    717    * @param delegate the multimap for which an unmodifiable view is to be
    718    *     returned
    719    * @return an unmodifiable view of the specified multimap
    720    */
    721   public static <K, V> SetMultimap<K, V> unmodifiableSetMultimap(
    722       SetMultimap<K, V> delegate) {
    723     return new UnmodifiableSetMultimap<K, V>(delegate);
    724   }
    725 
    726   /**
    727    * Returns a synchronized (thread-safe) {@code SortedSetMultimap} backed by
    728    * the specified multimap.
    729    *
    730    * <p>You must follow the warnings described in {@link #synchronizedMultimap}.
    731    *
    732    * <p>The returned multimap will be serializable if the specified multimap is
    733    * serializable.
    734    *
    735    * @param multimap the multimap to be wrapped
    736    * @return a synchronized view of the specified multimap
    737    */
    738   public static <K, V> SortedSetMultimap<K, V>
    739       synchronizedSortedSetMultimap(SortedSetMultimap<K, V> multimap) {
    740     return Synchronized.sortedSetMultimap(multimap, null);
    741   }
    742 
    743   /**
    744    * Returns an unmodifiable view of the specified {@code SortedSetMultimap}.
    745    * Query operations on the returned multimap "read through" to the specified
    746    * multimap, and attempts to modify the returned multimap, either directly or
    747    * through the multimap's views, result in an
    748    * {@code UnsupportedOperationException}.
    749    *
    750    * <p>Note that the generated multimap's {@link Multimap#removeAll} and
    751    * {@link Multimap#replaceValues} methods return collections that are
    752    * modifiable.
    753    *
    754    * <p>The returned multimap will be serializable if the specified multimap is
    755    * serializable.
    756    *
    757    * @param delegate the multimap for which an unmodifiable view is to be
    758    *     returned
    759    * @return an unmodifiable view of the specified multimap
    760    */
    761   public static <K, V> SortedSetMultimap<K, V> unmodifiableSortedSetMultimap(
    762       SortedSetMultimap<K, V> delegate) {
    763     return new UnmodifiableSortedSetMultimap<K, V>(delegate);
    764   }
    765 
    766   /**
    767    * Returns a synchronized (thread-safe) {@code ListMultimap} backed by the
    768    * specified multimap.
    769    *
    770    * <p>You must follow the warnings described in {@link #synchronizedMultimap}.
    771    *
    772    * @param multimap the multimap to be wrapped
    773    * @return a synchronized view of the specified multimap
    774    */
    775   public static <K, V> ListMultimap<K, V> synchronizedListMultimap(
    776       ListMultimap<K, V> multimap) {
    777     return Synchronized.listMultimap(multimap, null);
    778   }
    779 
    780   /**
    781    * Returns an unmodifiable view of the specified {@code ListMultimap}. Query
    782    * operations on the returned multimap "read through" to the specified
    783    * multimap, and attempts to modify the returned multimap, either directly or
    784    * through the multimap's views, result in an
    785    * {@code UnsupportedOperationException}.
    786    *
    787    * <p>Note that the generated multimap's {@link Multimap#removeAll} and
    788    * {@link Multimap#replaceValues} methods return collections that are
    789    * modifiable.
    790    *
    791    * <p>The returned multimap will be serializable if the specified multimap is
    792    * serializable.
    793    *
    794    * @param delegate the multimap for which an unmodifiable view is to be
    795    *     returned
    796    * @return an unmodifiable view of the specified multimap
    797    */
    798   public static <K, V> ListMultimap<K, V> unmodifiableListMultimap(
    799       ListMultimap<K, V> delegate) {
    800     return new UnmodifiableListMultimap<K, V>(delegate);
    801   }
    802 
    803   /**
    804    * Returns an unmodifiable view of the specified collection, preserving the
    805    * interface for instances of {@code SortedSet}, {@code Set}, {@code List} and
    806    * {@code Collection}, in that order of preference.
    807    *
    808    * @param collection the collection for which to return an unmodifiable view
    809    * @return an unmodifiable view of the collection
    810    */
    811   private static <V> Collection<V> unmodifiableValueCollection(
    812       Collection<V> collection) {
    813     if (collection instanceof SortedSet) {
    814       return Collections.unmodifiableSortedSet((SortedSet<V>) collection);
    815     } else if (collection instanceof Set) {
    816       return Collections.unmodifiableSet((Set<V>) collection);
    817     } else if (collection instanceof List) {
    818       return Collections.unmodifiableList((List<V>) collection);
    819     }
    820     return Collections.unmodifiableCollection(collection);
    821   }
    822 
    823   /**
    824    * Returns an unmodifiable view of the specified multimap {@code asMap} entry.
    825    * The {@link Entry#setValue} operation throws an {@link
    826    * UnsupportedOperationException}, and the collection returned by {@code
    827    * getValue} is also an unmodifiable (type-preserving) view. This also has the
    828    * side-effect of redefining equals to comply with the Map.Entry contract, and
    829    * to avoid a possible nefarious implementation of equals.
    830    *
    831    * @param entry the entry for which to return an unmodifiable view
    832    * @return an unmodifiable view of the entry
    833    */
    834   private static <K, V> Map.Entry<K, Collection<V>> unmodifiableAsMapEntry(
    835       final Map.Entry<K, Collection<V>> entry) {
    836     checkNotNull(entry);
    837     return new AbstractMapEntry<K, Collection<V>>() {
    838       @Override public K getKey() {
    839         return entry.getKey();
    840       }
    841 
    842       @Override public Collection<V> getValue() {
    843         return unmodifiableValueCollection(entry.getValue());
    844       }
    845     };
    846   }
    847 
    848   /**
    849    * Returns an unmodifiable view of the specified collection of entries. The
    850    * {@link Entry#setValue} operation throws an {@link
    851    * UnsupportedOperationException}. If the specified collection is a {@code
    852    * Set}, the returned collection is also a {@code Set}.
    853    *
    854    * @param entries the entries for which to return an unmodifiable view
    855    * @return an unmodifiable view of the entries
    856    */
    857   private static <K, V> Collection<Entry<K, V>> unmodifiableEntries(
    858       Collection<Entry<K, V>> entries) {
    859     if (entries instanceof Set) {
    860       return Maps.unmodifiableEntrySet((Set<Entry<K, V>>) entries);
    861     }
    862     return new Maps.UnmodifiableEntries<K, V>(
    863         Collections.unmodifiableCollection(entries));
    864   }
    865 
    866   /**
    867    * Returns an unmodifiable view of the specified set of {@code asMap} entries.
    868    * The {@link Entry#setValue} operation throws an {@link
    869    * UnsupportedOperationException}, as do any operations that attempt to modify
    870    * the returned collection.
    871    *
    872    * @param asMapEntries the {@code asMap} entries for which to return an
    873    *     unmodifiable view
    874    * @return an unmodifiable view of the collection entries
    875    */
    876   private static <K, V> Set<Entry<K, Collection<V>>> unmodifiableAsMapEntries(
    877       Set<Entry<K, Collection<V>>> asMapEntries) {
    878     return new UnmodifiableAsMapEntries<K, V>(
    879         Collections.unmodifiableSet(asMapEntries));
    880   }
    881 
    882   /** @see Multimaps#unmodifiableAsMapEntries */
    883   static class UnmodifiableAsMapEntries<K, V>
    884       extends ForwardingSet<Entry<K, Collection<V>>> {
    885     private final Set<Entry<K, Collection<V>>> delegate;
    886     UnmodifiableAsMapEntries(Set<Entry<K, Collection<V>>> delegate) {
    887       this.delegate = delegate;
    888     }
    889 
    890     @Override protected Set<Entry<K, Collection<V>>> delegate() {
    891       return delegate;
    892     }
    893 
    894     @Override public Iterator<Entry<K, Collection<V>>> iterator() {
    895       final Iterator<Entry<K, Collection<V>>> iterator = delegate.iterator();
    896       return new ForwardingIterator<Entry<K, Collection<V>>>() {
    897         @Override protected Iterator<Entry<K, Collection<V>>> delegate() {
    898           return iterator;
    899         }
    900         @Override public Entry<K, Collection<V>> next() {
    901           return unmodifiableAsMapEntry(iterator.next());
    902         }
    903       };
    904     }
    905 
    906     @Override public Object[] toArray() {
    907       return ObjectArrays.toArrayImpl(this);
    908     }
    909 
    910     @Override public <T> T[] toArray(T[] array) {
    911       return ObjectArrays.toArrayImpl(this, array);
    912     }
    913 
    914     @Override public boolean contains(Object o) {
    915       return Maps.containsEntryImpl(delegate(), o);
    916     }
    917 
    918     @Override public boolean containsAll(Collection<?> c) {
    919       return Collections2.containsAll(this, c);
    920     }
    921 
    922     @Override public boolean equals(@Nullable Object object) {
    923       return Collections2.setEquals(this, object);
    924     }
    925   }
    926 
    927   /**
    928    * Returns a multimap view of the specified map. The multimap is backed by the
    929    * map, so changes to the map are reflected in the multimap, and vice versa.
    930    * If the map is modified while an iteration over one of the multimap's
    931    * collection views is in progress (except through the iterator's own {@code
    932    * remove} operation, or through the {@code setValue} operation on a map entry
    933    * returned by the iterator), the results of the iteration are undefined.
    934    *
    935    * <p>The multimap supports mapping removal, which removes the corresponding
    936    * mapping from the map. It does not support any operations which might add
    937    * mappings, such as {@code put}, {@code putAll} or {@code replaceValues}.
    938    *
    939    * <p>The returned multimap will be serializable if the specified map is
    940    * serializable.
    941    *
    942    * @param map the backing map for the returned multimap view
    943    */
    944   public static <K, V> SetMultimap<K, V> forMap(Map<K, V> map) {
    945     return new MapMultimap<K, V>(map);
    946   }
    947 
    948   /** @see Multimaps#forMap */
    949   private static class MapMultimap<K, V>
    950       implements SetMultimap<K, V>, Serializable {
    951     final Map<K, V> map;
    952     transient Map<K, Collection<V>> asMap;
    953 
    954     MapMultimap(Map<K, V> map) {
    955       this.map = checkNotNull(map);
    956     }
    957 
    958     public int size() {
    959       return map.size();
    960     }
    961 
    962     public boolean isEmpty() {
    963       return map.isEmpty();
    964     }
    965 
    966     public boolean containsKey(Object key) {
    967       return map.containsKey(key);
    968     }
    969 
    970     public boolean containsValue(Object value) {
    971       return map.containsValue(value);
    972     }
    973 
    974     public boolean containsEntry(Object key, Object value) {
    975       return map.entrySet().contains(Maps.immutableEntry(key, value));
    976     }
    977 
    978     public Set<V> get(final K key) {
    979       return new AbstractSet<V>() {
    980         @Override public Iterator<V> iterator() {
    981           return new Iterator<V>() {
    982             int i;
    983 
    984             public boolean hasNext() {
    985               return (i == 0) && map.containsKey(key);
    986             }
    987 
    988             public V next() {
    989               if (!hasNext()) {
    990                 throw new NoSuchElementException();
    991               }
    992               i++;
    993               return map.get(key);
    994             }
    995 
    996             public void remove() {
    997               checkState(i == 1);
    998               i = -1;
    999               map.remove(key);
   1000             }
   1001           };
   1002         }
   1003 
   1004         @Override public int size() {
   1005           return map.containsKey(key) ? 1 : 0;
   1006         }
   1007       };
   1008     }
   1009 
   1010     public boolean put(K key, V value) {
   1011       throw new UnsupportedOperationException();
   1012     }
   1013 
   1014     public boolean putAll(K key, Iterable<? extends V> values) {
   1015       throw new UnsupportedOperationException();
   1016     }
   1017 
   1018     public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
   1019       throw new UnsupportedOperationException();
   1020     }
   1021 
   1022     public Set<V> replaceValues(K key, Iterable<? extends V> values) {
   1023       throw new UnsupportedOperationException();
   1024     }
   1025 
   1026     public boolean remove(Object key, Object value) {
   1027       return map.entrySet().remove(Maps.immutableEntry(key, value));
   1028     }
   1029 
   1030     public Set<V> removeAll(Object key) {
   1031       Set<V> values = new HashSet<V>(2);
   1032       if (!map.containsKey(key)) {
   1033         return values;
   1034       }
   1035       values.add(map.remove(key));
   1036       return values;
   1037     }
   1038 
   1039     public void clear() {
   1040       map.clear();
   1041     }
   1042 
   1043     public Set<K> keySet() {
   1044       return map.keySet();
   1045     }
   1046 
   1047     public Multiset<K> keys() {
   1048       return Multisets.forSet(map.keySet());
   1049     }
   1050 
   1051     public Collection<V> values() {
   1052       return map.values();
   1053     }
   1054 
   1055     public Set<Entry<K, V>> entries() {
   1056       return map.entrySet();
   1057     }
   1058 
   1059     public Map<K, Collection<V>> asMap() {
   1060       Map<K, Collection<V>> result = asMap;
   1061       if (result == null) {
   1062         asMap = result = new AsMap();
   1063       }
   1064       return result;
   1065     }
   1066 
   1067     @Override public boolean equals(@Nullable Object object) {
   1068       if (object == this) {
   1069         return true;
   1070       }
   1071       if (object instanceof Multimap) {
   1072         Multimap<?, ?> that = (Multimap<?, ?>) object;
   1073         return this.size() == that.size() && asMap().equals(that.asMap());
   1074       }
   1075       return false;
   1076     }
   1077 
   1078     @Override public int hashCode() {
   1079       return map.hashCode();
   1080     }
   1081 
   1082     private static final MapJoiner joiner
   1083         = Joiner.on("], ").withKeyValueSeparator("=[").useForNull("null");
   1084 
   1085     @Override public String toString() {
   1086       if (map.isEmpty()) {
   1087         return "{}";
   1088       }
   1089       StringBuilder builder = new StringBuilder(map.size() * 16).append('{');
   1090       joiner.appendTo(builder, map);
   1091       return builder.append("]}").toString();
   1092     }
   1093 
   1094     /** @see MapMultimap#asMap */
   1095     class AsMapEntries extends AbstractSet<Entry<K, Collection<V>>> {
   1096       @Override public int size() {
   1097         return map.size();
   1098       }
   1099 
   1100       @Override public Iterator<Entry<K, Collection<V>>> iterator() {
   1101         return new Iterator<Entry<K, Collection<V>>>() {
   1102           final Iterator<K> keys = map.keySet().iterator();
   1103 
   1104           public boolean hasNext() {
   1105             return keys.hasNext();
   1106           }
   1107           public Entry<K, Collection<V>> next() {
   1108             final K key = keys.next();
   1109             return new AbstractMapEntry<K, Collection<V>>() {
   1110               @Override public K getKey() {
   1111                 return key;
   1112               }
   1113               @Override public Collection<V> getValue() {
   1114                 return get(key);
   1115               }
   1116             };
   1117           }
   1118           public void remove() {
   1119             keys.remove();
   1120           }
   1121         };
   1122       }
   1123 
   1124       @Override public boolean contains(Object o) {
   1125         if (!(o instanceof Entry)) {
   1126           return false;
   1127         }
   1128         Entry<?, ?> entry = (Entry<?, ?>) o;
   1129         if (!(entry.getValue() instanceof Set)) {
   1130           return false;
   1131         }
   1132         Set<?> set = (Set<?>) entry.getValue();
   1133         return (set.size() == 1)
   1134             && containsEntry(entry.getKey(), set.iterator().next());
   1135       }
   1136 
   1137       @Override public boolean remove(Object o) {
   1138         if (!(o instanceof Entry)) {
   1139           return false;
   1140         }
   1141         Entry<?, ?> entry = (Entry<?, ?>) o;
   1142         if (!(entry.getValue() instanceof Set)) {
   1143           return false;
   1144         }
   1145         Set<?> set = (Set<?>) entry.getValue();
   1146         return (set.size() == 1)
   1147             && map.entrySet().remove(
   1148                 Maps.immutableEntry(entry.getKey(), set.iterator().next()));
   1149       }
   1150     }
   1151 
   1152     /** @see MapMultimap#asMap */
   1153     class AsMap extends Maps.ImprovedAbstractMap<K, Collection<V>> {
   1154       @Override protected Set<Entry<K, Collection<V>>> createEntrySet() {
   1155         return new AsMapEntries();
   1156       }
   1157 
   1158       // The following methods are included for performance.
   1159 
   1160       @Override public boolean containsKey(Object key) {
   1161         return map.containsKey(key);
   1162       }
   1163 
   1164       @SuppressWarnings("unchecked")
   1165       @Override public Collection<V> get(Object key) {
   1166         Collection<V> collection = MapMultimap.this.get((K) key);
   1167         return collection.isEmpty() ? null : collection;
   1168       }
   1169 
   1170       @Override public Collection<V> remove(Object key) {
   1171         Collection<V> collection = removeAll(key);
   1172         return collection.isEmpty() ? null : collection;
   1173       }
   1174     }
   1175     private static final long serialVersionUID = 7845222491160860175L;
   1176   }
   1177 
   1178   /**
   1179    * Creates an index {@code ImmutableMultimap} that contains the results of
   1180    * applying a specified function to each item in an {@code Iterable} of
   1181    * values. Each value will be stored as a value in the resulting multimap,
   1182    * yielding a multimap with the same size as the input iterable. The key used
   1183    * to store that value in the multimap will be the result of calling the
   1184    * function on that value. The resulting multimap is created as an immutable
   1185    * snapshot, it does <em>not</em> reflect subsequent changes on the input
   1186    * iterable.
   1187    *
   1188    * <p>For example, <pre class="code">  {@code
   1189    *
   1190    *  List<String> badGuys
   1191    *      = Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde");
   1192    *  Function<String, Integer> stringLengthFunction = ...;
   1193    *  Multimap<Integer, String> index
   1194    *      = Multimaps.index(badGuys, stringLengthFunction);
   1195    *  System.out.println(index);}</pre>
   1196    *
   1197    * prints <pre class="code">  {@code
   1198    *
   1199    *  {4=[Inky], 5=[Pinky, Pinky, Clyde], 6=[Blinky]}}</pre>
   1200    *
   1201    * <p>The returned multimap is serializable if its keys and values are all
   1202    * serializable.
   1203    *
   1204    * @param values the values to use when constructing the {@code
   1205    *     ImmutableMultimap}
   1206    * @param keyFunction the function used to produce the key for each value
   1207    * @return {@code ImmutableMultimap} mapping the result of evaluating the
   1208    *     function {@code keyFunction} on each value in the input collection to
   1209    *     that value
   1210    * @throws NullPointerException if any of the following cases is true: <ul>
   1211    * <li> {@code values} is null
   1212    * <li> {@code keyFunction} is null
   1213    * <li> An element in {@code values} is null
   1214    * <li> {@code keyFunction} returns null for any element of {@code values}
   1215    * </ul>
   1216    */
   1217   public static <K, V> ImmutableListMultimap<K, V> index(
   1218       Iterable<V> values, Function<? super V, K> keyFunction) {
   1219     checkNotNull(keyFunction);
   1220     ImmutableListMultimap.Builder<K, V> builder
   1221         = ImmutableListMultimap.builder();
   1222     for (V value : values) {
   1223       Preconditions.checkNotNull(value, values);
   1224       builder.put(keyFunction.apply(value), value);
   1225     }
   1226     return builder.build();
   1227   }
   1228 }
   1229