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