• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Guava Authors
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 static com.google.common.base.Preconditions.checkArgument;
20 import static com.google.common.base.Preconditions.checkNotNull;
21 import static com.google.common.base.Preconditions.checkState;
22 
23 import com.google.common.annotations.GwtCompatible;
24 
25 import java.io.Serializable;
26 import java.util.AbstractCollection;
27 import java.util.AbstractMap;
28 import java.util.Collection;
29 import java.util.Collections;
30 import java.util.Comparator;
31 import java.util.ConcurrentModificationException;
32 import java.util.Iterator;
33 import java.util.List;
34 import java.util.ListIterator;
35 import java.util.Map;
36 import java.util.Map.Entry;
37 import java.util.RandomAccess;
38 import java.util.Set;
39 import java.util.SortedMap;
40 import java.util.SortedSet;
41 
42 import javax.annotation.Nullable;
43 
44 /**
45  * Basic implementation of the {@link Multimap} interface. This class represents
46  * a multimap as a map that associates each key with a collection of values. All
47  * methods of {@link Multimap} are supported, including those specified as
48  * optional in the interface.
49  *
50  * <p>To implement a multimap, a subclass must define the method {@link
51  * #createCollection()}, which creates an empty collection of values for a key.
52  *
53  * <p>The multimap constructor takes a map that has a single entry for each
54  * distinct key. When you insert a key-value pair with a key that isn't already
55  * in the multimap, {@code AbstractMultimap} calls {@link #createCollection()}
56  * to create the collection of values for that key. The subclass should not call
57  * {@link #createCollection()} directly, and a new instance should be created
58  * every time the method is called.
59  *
60  * <p>For example, the subclass could pass a {@link java.util.TreeMap} during
61  * construction, and {@link #createCollection()} could return a {@link
62  * java.util.TreeSet}, in which case the multimap's iterators would propagate
63  * through the keys and values in sorted order.
64  *
65  * <p>Keys and values may be null, as long as the underlying collection classes
66  * support null elements.
67  *
68  * <p>The collections created by {@link #createCollection()} may or may not
69  * allow duplicates. If the collection, such as a {@link Set}, does not support
70  * duplicates, an added key-value pair will replace an existing pair with the
71  * same key and value, if such a pair is present. With collections like {@link
72  * List} that allow duplicates, the collection will keep the existing key-value
73  * pairs while adding a new pair.
74  *
75  * <p>This class is not threadsafe when any concurrent operations update the
76  * multimap, even if the underlying map and {@link #createCollection()} method
77  * return threadsafe classes. Concurrent read operations will work correctly. To
78  * allow concurrent update operations, wrap your multimap with a call to {@link
79  * Multimaps#synchronizedMultimap}.
80  *
81  * <p>For serialization to work, the subclass must specify explicit
82  * {@code readObject} and {@code writeObject} methods.
83  *
84  * @author Jared Levy
85  * @author Louis Wasserman
86  */
87 @GwtCompatible
88 abstract class AbstractMultimap<K, V> implements Multimap<K, V>, Serializable {
89   /*
90    * Here's an outline of the overall design.
91    *
92    * The map variable contains the collection of values associated with each
93    * key. When a key-value pair is added to a multimap that didn't previously
94    * contain any values for that key, a new collection generated by
95    * createCollection is added to the map. That same collection instance
96    * remains in the map as long as the multimap has any values for the key. If
97    * all values for the key are removed, the key and collection are removed
98    * from the map.
99    *
100    * The get method returns a WrappedCollection, which decorates the collection
101    * in the map (if the key is present) or an empty collection (if the key is
102    * not present). When the collection delegate in the WrappedCollection is
103    * empty, the multimap may contain subsequently added values for that key. To
104    * handle that situation, the WrappedCollection checks whether map contains
105    * an entry for the provided key, and if so replaces the delegate.
106    */
107 
108   private transient Map<K, Collection<V>> map;
109   private transient int totalSize;
110 
111   /**
112    * Creates a new multimap that uses the provided map.
113    *
114    * @param map place to store the mapping from each key to its corresponding
115    *     values
116    * @throws IllegalArgumentException if {@code map} is not empty
117    */
AbstractMultimap(Map<K, Collection<V>> map)118   protected AbstractMultimap(Map<K, Collection<V>> map) {
119     checkArgument(map.isEmpty());
120     this.map = map;
121   }
122 
123   /** Used during deserialization only. */
setMap(Map<K, Collection<V>> map)124   final void setMap(Map<K, Collection<V>> map) {
125     this.map = map;
126     totalSize = 0;
127     for (Collection<V> values : map.values()) {
128       checkArgument(!values.isEmpty());
129       totalSize += values.size();
130     }
131   }
132 
133   /**
134    * Creates the collection of values for a single key.
135    *
136    * <p>Collections with weak, soft, or phantom references are not supported.
137    * Each call to {@code createCollection} should create a new instance.
138    *
139    * <p>The returned collection class determines whether duplicate key-value
140    * pairs are allowed.
141    *
142    * @return an empty collection of values
143    */
createCollection()144   abstract Collection<V> createCollection();
145 
146   /**
147    * Creates the collection of values for an explicitly provided key. By
148    * default, it simply calls {@link #createCollection()}, which is the correct
149    * behavior for most implementations. The {@link LinkedHashMultimap} class
150    * overrides it.
151    *
152    * @param key key to associate with values in the collection
153    * @return an empty collection of values
154    */
createCollection(@ullable K key)155   Collection<V> createCollection(@Nullable K key) {
156     return createCollection();
157   }
158 
backingMap()159   Map<K, Collection<V>> backingMap() {
160     return map;
161   }
162 
163   // Query Operations
164 
165   @Override
size()166   public int size() {
167     return totalSize;
168   }
169 
170   @Override
isEmpty()171   public boolean isEmpty() {
172     return totalSize == 0;
173   }
174 
175   @Override
containsKey(@ullable Object key)176   public boolean containsKey(@Nullable Object key) {
177     return map.containsKey(key);
178   }
179 
180   @Override
containsValue(@ullable Object value)181   public boolean containsValue(@Nullable Object value) {
182     for (Collection<V> collection : map.values()) {
183       if (collection.contains(value)) {
184         return true;
185       }
186     }
187 
188     return false;
189   }
190 
191   @Override
containsEntry(@ullable Object key, @Nullable Object value)192   public boolean containsEntry(@Nullable Object key, @Nullable Object value) {
193     Collection<V> collection = map.get(key);
194     return collection != null && collection.contains(value);
195   }
196 
197   // Modification Operations
198 
199   @Override
put(@ullable K key, @Nullable V value)200   public boolean put(@Nullable K key, @Nullable V value) {
201     Collection<V> collection = getOrCreateCollection(key);
202 
203     if (collection.add(value)) {
204       totalSize++;
205       return true;
206     } else {
207       return false;
208     }
209   }
210 
getOrCreateCollection(@ullable K key)211   private Collection<V> getOrCreateCollection(@Nullable K key) {
212     Collection<V> collection = map.get(key);
213     if (collection == null) {
214       collection = createCollection(key);
215       map.put(key, collection);
216     }
217     return collection;
218   }
219 
220   @Override
remove(@ullable Object key, @Nullable Object value)221   public boolean remove(@Nullable Object key, @Nullable Object value) {
222     Collection<V> collection = map.get(key);
223     if (collection == null) {
224       return false;
225     }
226 
227     boolean changed = collection.remove(value);
228     if (changed) {
229       totalSize--;
230       if (collection.isEmpty()) {
231         map.remove(key);
232       }
233     }
234     return changed;
235   }
236 
237   // Bulk Operations
238 
239   @Override
putAll(@ullable K key, Iterable<? extends V> values)240   public boolean putAll(@Nullable K key, Iterable<? extends V> values) {
241     if (!values.iterator().hasNext()) {
242       return false;
243     }
244     Collection<V> collection = getOrCreateCollection(key);
245     int oldSize = collection.size();
246 
247     boolean changed = false;
248     if (values instanceof Collection) {
249       Collection<? extends V> c = Collections2.cast(values);
250       changed = collection.addAll(c);
251     } else {
252       for (V value : values) {
253         changed |= collection.add(value);
254       }
255     }
256 
257     totalSize += (collection.size() - oldSize);
258     return changed;
259   }
260 
261   @Override
putAll(Multimap<? extends K, ? extends V> multimap)262   public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
263     boolean changed = false;
264     for (Map.Entry<? extends K, ? extends V> entry : multimap.entries()) {
265       changed |= put(entry.getKey(), entry.getValue());
266     }
267     return changed;
268   }
269 
270   /**
271    * {@inheritDoc}
272    *
273    * <p>The returned collection is immutable.
274    */
275   @Override
replaceValues( @ullable K key, Iterable<? extends V> values)276   public Collection<V> replaceValues(
277       @Nullable K key, Iterable<? extends V> values) {
278     Iterator<? extends V> iterator = values.iterator();
279     if (!iterator.hasNext()) {
280       return removeAll(key);
281     }
282 
283     Collection<V> collection = getOrCreateCollection(key);
284     Collection<V> oldValues = createCollection();
285     oldValues.addAll(collection);
286 
287     totalSize -= collection.size();
288     collection.clear();
289 
290     while (iterator.hasNext()) {
291       if (collection.add(iterator.next())) {
292         totalSize++;
293       }
294     }
295 
296     return unmodifiableCollectionSubclass(oldValues);
297   }
298 
299   /**
300    * {@inheritDoc}
301    *
302    * <p>The returned collection is immutable.
303    */
304   @Override
removeAll(@ullable Object key)305   public Collection<V> removeAll(@Nullable Object key) {
306     Collection<V> collection = map.remove(key);
307     Collection<V> output = createCollection();
308 
309     if (collection != null) {
310       output.addAll(collection);
311       totalSize -= collection.size();
312       collection.clear();
313     }
314 
315     return unmodifiableCollectionSubclass(output);
316   }
317 
unmodifiableCollectionSubclass( Collection<V> collection)318   private Collection<V> unmodifiableCollectionSubclass(
319       Collection<V> collection) {
320     if (collection instanceof SortedSet) {
321       return Collections.unmodifiableSortedSet((SortedSet<V>) collection);
322     } else if (collection instanceof Set) {
323       return Collections.unmodifiableSet((Set<V>) collection);
324     } else if (collection instanceof List) {
325       return Collections.unmodifiableList((List<V>) collection);
326     } else {
327       return Collections.unmodifiableCollection(collection);
328     }
329   }
330 
331   @Override
clear()332   public void clear() {
333     // Clear each collection, to make previously returned collections empty.
334     for (Collection<V> collection : map.values()) {
335       collection.clear();
336     }
337     map.clear();
338     totalSize = 0;
339   }
340 
341   // Views
342 
343   /**
344    * {@inheritDoc}
345    *
346    * <p>The returned collection is not serializable.
347    */
348   @Override
get(@ullable K key)349   public Collection<V> get(@Nullable K key) {
350     Collection<V> collection = map.get(key);
351     if (collection == null) {
352       collection = createCollection(key);
353     }
354     return wrapCollection(key, collection);
355   }
356 
357   /**
358    * Generates a decorated collection that remains consistent with the values in
359    * the multimap for the provided key. Changes to the multimap may alter the
360    * returned collection, and vice versa.
361    */
wrapCollection( @ullable K key, Collection<V> collection)362   private Collection<V> wrapCollection(
363       @Nullable K key, Collection<V> collection) {
364     if (collection instanceof SortedSet) {
365       return new WrappedSortedSet(key, (SortedSet<V>) collection, null);
366     } else if (collection instanceof Set) {
367       return new WrappedSet(key, (Set<V>) collection);
368     } else if (collection instanceof List) {
369       return wrapList(key, (List<V>) collection, null);
370     } else {
371       return new WrappedCollection(key, collection, null);
372     }
373   }
374 
wrapList( @ullable K key, List<V> list, @Nullable WrappedCollection ancestor)375   private List<V> wrapList(
376       @Nullable K key, List<V> list, @Nullable WrappedCollection ancestor) {
377     return (list instanceof RandomAccess)
378         ? new RandomAccessWrappedList(key, list, ancestor)
379         : new WrappedList(key, list, ancestor);
380   }
381 
382   /**
383    * Collection decorator that stays in sync with the multimap values for a key.
384    * There are two kinds of wrapped collections: full and subcollections. Both
385    * have a delegate pointing to the underlying collection class.
386    *
387    * <p>Full collections, identified by a null ancestor field, contain all
388    * multimap values for a given key. Its delegate is a value in {@link
389    * AbstractMultimap#map} whenever the delegate is non-empty. The {@code
390    * refreshIfEmpty}, {@code removeIfEmpty}, and {@code addToMap} methods ensure
391    * that the {@code WrappedCollection} and map remain consistent.
392    *
393    * <p>A subcollection, such as a sublist, contains some of the values for a
394    * given key. Its ancestor field points to the full wrapped collection with
395    * all values for the key. The subcollection {@code refreshIfEmpty}, {@code
396    * removeIfEmpty}, and {@code addToMap} methods call the corresponding methods
397    * of the full wrapped collection.
398    */
399   private class WrappedCollection extends AbstractCollection<V> {
400     final K key;
401     Collection<V> delegate;
402     final WrappedCollection ancestor;
403     final Collection<V> ancestorDelegate;
404 
WrappedCollection(@ullable K key, Collection<V> delegate, @Nullable WrappedCollection ancestor)405     WrappedCollection(@Nullable K key, Collection<V> delegate,
406         @Nullable WrappedCollection ancestor) {
407       this.key = key;
408       this.delegate = delegate;
409       this.ancestor = ancestor;
410       this.ancestorDelegate
411           = (ancestor == null) ? null : ancestor.getDelegate();
412     }
413 
414     /**
415      * If the delegate collection is empty, but the multimap has values for the
416      * key, replace the delegate with the new collection for the key.
417      *
418      * <p>For a subcollection, refresh its ancestor and validate that the
419      * ancestor delegate hasn't changed.
420      */
refreshIfEmpty()421     void refreshIfEmpty() {
422       if (ancestor != null) {
423         ancestor.refreshIfEmpty();
424         if (ancestor.getDelegate() != ancestorDelegate) {
425           throw new ConcurrentModificationException();
426         }
427       } else if (delegate.isEmpty()) {
428         Collection<V> newDelegate = map.get(key);
429         if (newDelegate != null) {
430           delegate = newDelegate;
431         }
432       }
433     }
434 
435     /**
436      * If collection is empty, remove it from {@code AbstractMultimap.this.map}.
437      * For subcollections, check whether the ancestor collection is empty.
438      */
removeIfEmpty()439     void removeIfEmpty() {
440       if (ancestor != null) {
441         ancestor.removeIfEmpty();
442       } else if (delegate.isEmpty()) {
443         map.remove(key);
444       }
445     }
446 
getKey()447     K getKey() {
448       return key;
449     }
450 
451     /**
452      * Add the delegate to the map. Other {@code WrappedCollection} methods
453      * should call this method after adding elements to a previously empty
454      * collection.
455      *
456      * <p>Subcollection add the ancestor's delegate instead.
457      */
addToMap()458     void addToMap() {
459       if (ancestor != null) {
460         ancestor.addToMap();
461       } else {
462         map.put(key, delegate);
463       }
464     }
465 
size()466     @Override public int size() {
467       refreshIfEmpty();
468       return delegate.size();
469     }
470 
equals(@ullable Object object)471     @Override public boolean equals(@Nullable Object object) {
472       if (object == this) {
473         return true;
474       }
475       refreshIfEmpty();
476       return delegate.equals(object);
477     }
478 
hashCode()479     @Override public int hashCode() {
480       refreshIfEmpty();
481       return delegate.hashCode();
482     }
483 
toString()484     @Override public String toString() {
485       refreshIfEmpty();
486       return delegate.toString();
487     }
488 
getDelegate()489     Collection<V> getDelegate() {
490       return delegate;
491     }
492 
iterator()493     @Override public Iterator<V> iterator() {
494       refreshIfEmpty();
495       return new WrappedIterator();
496     }
497 
498     /** Collection iterator for {@code WrappedCollection}. */
499     class WrappedIterator implements Iterator<V> {
500       final Iterator<V> delegateIterator;
501       final Collection<V> originalDelegate = delegate;
502 
WrappedIterator()503       WrappedIterator() {
504         delegateIterator = iteratorOrListIterator(delegate);
505       }
506 
WrappedIterator(Iterator<V> delegateIterator)507       WrappedIterator(Iterator<V> delegateIterator) {
508         this.delegateIterator = delegateIterator;
509       }
510 
511       /**
512        * If the delegate changed since the iterator was created, the iterator is
513        * no longer valid.
514        */
validateIterator()515       void validateIterator() {
516         refreshIfEmpty();
517         if (delegate != originalDelegate) {
518           throw new ConcurrentModificationException();
519         }
520       }
521 
522       @Override
hasNext()523       public boolean hasNext() {
524         validateIterator();
525         return delegateIterator.hasNext();
526       }
527 
528       @Override
next()529       public V next() {
530         validateIterator();
531         return delegateIterator.next();
532       }
533 
534       @Override
remove()535       public void remove() {
536         delegateIterator.remove();
537         totalSize--;
538         removeIfEmpty();
539       }
540 
getDelegateIterator()541       Iterator<V> getDelegateIterator() {
542         validateIterator();
543         return delegateIterator;
544       }
545     }
546 
add(V value)547     @Override public boolean add(V value) {
548       refreshIfEmpty();
549       boolean wasEmpty = delegate.isEmpty();
550       boolean changed = delegate.add(value);
551       if (changed) {
552         totalSize++;
553         if (wasEmpty) {
554           addToMap();
555         }
556       }
557       return changed;
558     }
559 
getAncestor()560     WrappedCollection getAncestor() {
561       return ancestor;
562     }
563 
564     // The following methods are provided for better performance.
565 
addAll(Collection<? extends V> collection)566     @Override public boolean addAll(Collection<? extends V> collection) {
567       if (collection.isEmpty()) {
568         return false;
569       }
570       int oldSize = size();  // calls refreshIfEmpty
571       boolean changed = delegate.addAll(collection);
572       if (changed) {
573         int newSize = delegate.size();
574         totalSize += (newSize - oldSize);
575         if (oldSize == 0) {
576           addToMap();
577         }
578       }
579       return changed;
580     }
581 
contains(Object o)582     @Override public boolean contains(Object o) {
583       refreshIfEmpty();
584       return delegate.contains(o);
585     }
586 
containsAll(Collection<?> c)587     @Override public boolean containsAll(Collection<?> c) {
588       refreshIfEmpty();
589       return delegate.containsAll(c);
590     }
591 
clear()592     @Override public void clear() {
593       int oldSize = size();  // calls refreshIfEmpty
594       if (oldSize == 0) {
595         return;
596       }
597       delegate.clear();
598       totalSize -= oldSize;
599       removeIfEmpty();       // maybe shouldn't be removed if this is a sublist
600     }
601 
remove(Object o)602     @Override public boolean remove(Object o) {
603       refreshIfEmpty();
604       boolean changed = delegate.remove(o);
605       if (changed) {
606         totalSize--;
607         removeIfEmpty();
608       }
609       return changed;
610     }
611 
removeAll(Collection<?> c)612     @Override public boolean removeAll(Collection<?> c) {
613       if (c.isEmpty()) {
614         return false;
615       }
616       int oldSize = size();  // calls refreshIfEmpty
617       boolean changed = delegate.removeAll(c);
618       if (changed) {
619         int newSize = delegate.size();
620         totalSize += (newSize - oldSize);
621         removeIfEmpty();
622       }
623       return changed;
624     }
625 
retainAll(Collection<?> c)626     @Override public boolean retainAll(Collection<?> c) {
627       checkNotNull(c);
628       int oldSize = size();  // calls refreshIfEmpty
629       boolean changed = delegate.retainAll(c);
630       if (changed) {
631         int newSize = delegate.size();
632         totalSize += (newSize - oldSize);
633         removeIfEmpty();
634       }
635       return changed;
636     }
637   }
638 
iteratorOrListIterator(Collection<V> collection)639   private Iterator<V> iteratorOrListIterator(Collection<V> collection) {
640     return (collection instanceof List)
641         ? ((List<V>) collection).listIterator()
642         : collection.iterator();
643   }
644 
645   /** Set decorator that stays in sync with the multimap values for a key. */
646   private class WrappedSet extends WrappedCollection implements Set<V> {
WrappedSet(@ullable K key, Set<V> delegate)647     WrappedSet(@Nullable K key, Set<V> delegate) {
648       super(key, delegate, null);
649     }
650   }
651 
652   /**
653    * SortedSet decorator that stays in sync with the multimap values for a key.
654    */
655   private class WrappedSortedSet extends WrappedCollection
656       implements SortedSet<V> {
WrappedSortedSet(@ullable K key, SortedSet<V> delegate, @Nullable WrappedCollection ancestor)657     WrappedSortedSet(@Nullable K key, SortedSet<V> delegate,
658         @Nullable WrappedCollection ancestor) {
659       super(key, delegate, ancestor);
660     }
661 
getSortedSetDelegate()662     SortedSet<V> getSortedSetDelegate() {
663       return (SortedSet<V>) getDelegate();
664     }
665 
666     @Override
comparator()667     public Comparator<? super V> comparator() {
668       return getSortedSetDelegate().comparator();
669     }
670 
671     @Override
first()672     public V first() {
673       refreshIfEmpty();
674       return getSortedSetDelegate().first();
675     }
676 
677     @Override
last()678     public V last() {
679       refreshIfEmpty();
680       return getSortedSetDelegate().last();
681     }
682 
683     @Override
headSet(V toElement)684     public SortedSet<V> headSet(V toElement) {
685       refreshIfEmpty();
686       return new WrappedSortedSet(
687           getKey(), getSortedSetDelegate().headSet(toElement),
688           (getAncestor() == null) ? this : getAncestor());
689     }
690 
691     @Override
subSet(V fromElement, V toElement)692     public SortedSet<V> subSet(V fromElement, V toElement) {
693       refreshIfEmpty();
694       return new WrappedSortedSet(
695           getKey(), getSortedSetDelegate().subSet(fromElement, toElement),
696           (getAncestor() == null) ? this : getAncestor());
697     }
698 
699     @Override
tailSet(V fromElement)700     public SortedSet<V> tailSet(V fromElement) {
701       refreshIfEmpty();
702       return new WrappedSortedSet(
703           getKey(), getSortedSetDelegate().tailSet(fromElement),
704           (getAncestor() == null) ? this : getAncestor());
705     }
706   }
707 
708   /** List decorator that stays in sync with the multimap values for a key. */
709   private class WrappedList extends WrappedCollection implements List<V> {
WrappedList(@ullable K key, List<V> delegate, @Nullable WrappedCollection ancestor)710     WrappedList(@Nullable K key, List<V> delegate,
711         @Nullable WrappedCollection ancestor) {
712       super(key, delegate, ancestor);
713     }
714 
getListDelegate()715     List<V> getListDelegate() {
716       return (List<V>) getDelegate();
717     }
718 
719     @Override
addAll(int index, Collection<? extends V> c)720     public boolean addAll(int index, Collection<? extends V> c) {
721       if (c.isEmpty()) {
722         return false;
723       }
724       int oldSize = size();  // calls refreshIfEmpty
725       boolean changed = getListDelegate().addAll(index, c);
726       if (changed) {
727         int newSize = getDelegate().size();
728         totalSize += (newSize - oldSize);
729         if (oldSize == 0) {
730           addToMap();
731         }
732       }
733       return changed;
734     }
735 
736     @Override
get(int index)737     public V get(int index) {
738       refreshIfEmpty();
739       return getListDelegate().get(index);
740     }
741 
742     @Override
set(int index, V element)743     public V set(int index, V element) {
744       refreshIfEmpty();
745       return getListDelegate().set(index, element);
746     }
747 
748     @Override
add(int index, V element)749     public void add(int index, V element) {
750       refreshIfEmpty();
751       boolean wasEmpty = getDelegate().isEmpty();
752       getListDelegate().add(index, element);
753       totalSize++;
754       if (wasEmpty) {
755         addToMap();
756       }
757     }
758 
759     @Override
remove(int index)760     public V remove(int index) {
761       refreshIfEmpty();
762       V value = getListDelegate().remove(index);
763       totalSize--;
764       removeIfEmpty();
765       return value;
766     }
767 
768     @Override
indexOf(Object o)769     public int indexOf(Object o) {
770       refreshIfEmpty();
771       return getListDelegate().indexOf(o);
772     }
773 
774     @Override
lastIndexOf(Object o)775     public int lastIndexOf(Object o) {
776       refreshIfEmpty();
777       return getListDelegate().lastIndexOf(o);
778     }
779 
780     @Override
listIterator()781     public ListIterator<V> listIterator() {
782       refreshIfEmpty();
783       return new WrappedListIterator();
784     }
785 
786     @Override
listIterator(int index)787     public ListIterator<V> listIterator(int index) {
788       refreshIfEmpty();
789       return new WrappedListIterator(index);
790     }
791 
792     @Override
subList(int fromIndex, int toIndex)793     public List<V> subList(int fromIndex, int toIndex) {
794       refreshIfEmpty();
795       return wrapList(getKey(),
796           getListDelegate().subList(fromIndex, toIndex),
797           (getAncestor() == null) ? this : getAncestor());
798     }
799 
800     /** ListIterator decorator. */
801     private class WrappedListIterator extends WrappedIterator
802         implements ListIterator<V> {
WrappedListIterator()803       WrappedListIterator() {}
804 
WrappedListIterator(int index)805       public WrappedListIterator(int index) {
806         super(getListDelegate().listIterator(index));
807       }
808 
getDelegateListIterator()809       private ListIterator<V> getDelegateListIterator() {
810         return (ListIterator<V>) getDelegateIterator();
811       }
812 
813       @Override
hasPrevious()814       public boolean hasPrevious() {
815         return getDelegateListIterator().hasPrevious();
816       }
817 
818       @Override
previous()819       public V previous() {
820         return getDelegateListIterator().previous();
821       }
822 
823       @Override
nextIndex()824       public int nextIndex() {
825         return getDelegateListIterator().nextIndex();
826       }
827 
828       @Override
previousIndex()829       public int previousIndex() {
830         return getDelegateListIterator().previousIndex();
831       }
832 
833       @Override
set(V value)834       public void set(V value) {
835         getDelegateListIterator().set(value);
836       }
837 
838       @Override
add(V value)839       public void add(V value) {
840         boolean wasEmpty = isEmpty();
841         getDelegateListIterator().add(value);
842         totalSize++;
843         if (wasEmpty) {
844           addToMap();
845         }
846       }
847     }
848   }
849 
850   /**
851    * List decorator that stays in sync with the multimap values for a key and
852    * supports rapid random access.
853    */
854   private class RandomAccessWrappedList extends WrappedList
855       implements RandomAccess {
RandomAccessWrappedList(@ullable K key, List<V> delegate, @Nullable WrappedCollection ancestor)856     RandomAccessWrappedList(@Nullable K key, List<V> delegate,
857         @Nullable WrappedCollection ancestor) {
858       super(key, delegate, ancestor);
859     }
860   }
861 
862   private transient Set<K> keySet;
863 
864   @Override
keySet()865   public Set<K> keySet() {
866     Set<K> result = keySet;
867     return (result == null) ? keySet = createKeySet() : result;
868   }
869 
createKeySet()870   private Set<K> createKeySet() {
871     return (map instanceof SortedMap)
872         ? new SortedKeySet((SortedMap<K, Collection<V>>) map) : new KeySet(map);
873   }
874 
875   private class KeySet extends Maps.KeySet<K, Collection<V>> {
876 
877     /**
878      * This is usually the same as map, except when someone requests a
879      * subcollection of a {@link SortedKeySet}.
880      */
881     final Map<K, Collection<V>> subMap;
882 
KeySet(final Map<K, Collection<V>> subMap)883     KeySet(final Map<K, Collection<V>> subMap) {
884       this.subMap = subMap;
885     }
886 
887     @Override
map()888     Map<K, Collection<V>> map() {
889       return subMap;
890     }
891 
iterator()892     @Override public Iterator<K> iterator() {
893       return new Iterator<K>() {
894         final Iterator<Map.Entry<K, Collection<V>>> entryIterator
895             = subMap.entrySet().iterator();
896         Map.Entry<K, Collection<V>> entry;
897 
898         @Override
899         public boolean hasNext() {
900           return entryIterator.hasNext();
901         }
902         @Override
903         public K next() {
904           entry = entryIterator.next();
905           return entry.getKey();
906         }
907         @Override
908         public void remove() {
909           checkState(entry != null);
910           Collection<V> collection = entry.getValue();
911           entryIterator.remove();
912           totalSize -= collection.size();
913           collection.clear();
914         }
915       };
916     }
917 
918     // The following methods are included for better performance.
919 
remove(Object key)920     @Override public boolean remove(Object key) {
921       int count = 0;
922       Collection<V> collection = subMap.remove(key);
923       if (collection != null) {
924         count = collection.size();
925         collection.clear();
926         totalSize -= count;
927       }
928       return count > 0;
929     }
930 
931     @Override
clear()932     public void clear() {
933       Iterators.clear(iterator());
934     }
935 
containsAll(Collection<?> c)936     @Override public boolean containsAll(Collection<?> c) {
937       return subMap.keySet().containsAll(c);
938     }
939 
equals(@ullable Object object)940     @Override public boolean equals(@Nullable Object object) {
941       return this == object || this.subMap.keySet().equals(object);
942     }
943 
hashCode()944     @Override public int hashCode() {
945       return subMap.keySet().hashCode();
946     }
947   }
948 
949   private class SortedKeySet extends KeySet implements SortedSet<K> {
950 
SortedKeySet(SortedMap<K, Collection<V>> subMap)951     SortedKeySet(SortedMap<K, Collection<V>> subMap) {
952       super(subMap);
953     }
954 
sortedMap()955     SortedMap<K, Collection<V>> sortedMap() {
956       return (SortedMap<K, Collection<V>>) subMap;
957     }
958 
959     @Override
comparator()960     public Comparator<? super K> comparator() {
961       return sortedMap().comparator();
962     }
963 
964     @Override
first()965     public K first() {
966       return sortedMap().firstKey();
967     }
968 
969     @Override
headSet(K toElement)970     public SortedSet<K> headSet(K toElement) {
971       return new SortedKeySet(sortedMap().headMap(toElement));
972     }
973 
974     @Override
last()975     public K last() {
976       return sortedMap().lastKey();
977     }
978 
979     @Override
subSet(K fromElement, K toElement)980     public SortedSet<K> subSet(K fromElement, K toElement) {
981       return new SortedKeySet(sortedMap().subMap(fromElement, toElement));
982     }
983 
984     @Override
tailSet(K fromElement)985     public SortedSet<K> tailSet(K fromElement) {
986       return new SortedKeySet(sortedMap().tailMap(fromElement));
987     }
988   }
989 
990   private transient Multiset<K> multiset;
991 
992   @Override
keys()993   public Multiset<K> keys() {
994     Multiset<K> result = multiset;
995     if (result == null) {
996       return multiset = new Multimaps.Keys<K, V>() {
997         @Override Multimap<K, V> multimap() {
998           return AbstractMultimap.this;
999         }
1000       };
1001     }
1002     return result;
1003   }
1004 
1005   /**
1006    * Removes all values for the provided key. Unlike {@link #removeAll}, it
1007    * returns the number of removed mappings.
1008    */
1009   private int removeValuesForKey(Object key) {
1010     Collection<V> collection;
1011     try {
1012       collection = map.remove(key);
1013     } catch (NullPointerException e) {
1014       return 0;
1015     } catch (ClassCastException e) {
1016       return 0;
1017     }
1018 
1019     int count = 0;
1020     if (collection != null) {
1021       count = collection.size();
1022       collection.clear();
1023       totalSize -= count;
1024     }
1025     return count;
1026   }
1027 
1028   private transient Collection<V> valuesCollection;
1029 
1030   /**
1031    * {@inheritDoc}
1032    *
1033    * <p>The iterator generated by the returned collection traverses the values
1034    * for one key, followed by the values of a second key, and so on.
1035    */
1036   @Override public Collection<V> values() {
1037     Collection<V> result = valuesCollection;
1038     if (result == null) {
1039       return valuesCollection = new Multimaps.Values<K, V>() {
1040         @Override Multimap<K, V> multimap() {
1041           return AbstractMultimap.this;
1042         }
1043       };
1044     }
1045     return result;
1046   }
1047 
1048   private transient Collection<Map.Entry<K, V>> entries;
1049 
1050   /*
1051    * TODO(kevinb): should we copy this javadoc to each concrete class, so that
1052    * classes like LinkedHashMultimap that need to say something different are
1053    * still able to {@inheritDoc} all the way from Multimap?
1054    */
1055 
1056   /**
1057    * {@inheritDoc}
1058    *
1059    * <p>The iterator generated by the returned collection traverses the values
1060    * for one key, followed by the values of a second key, and so on.
1061    *
1062    * <p>Each entry is an immutable snapshot of a key-value mapping in the
1063    * multimap, taken at the time the entry is returned by a method call to the
1064    * collection or its iterator.
1065    */
1066   @Override
1067   public Collection<Map.Entry<K, V>> entries() {
1068     Collection<Map.Entry<K, V>> result = entries;
1069     return (result == null) ? entries = createEntries() : result;
1070   }
1071 
1072   Collection<Map.Entry<K, V>> createEntries() {
1073     if (this instanceof SetMultimap) {
1074       return new Multimaps.EntrySet<K, V>() {
1075         @Override Multimap<K, V> multimap() {
1076           return AbstractMultimap.this;
1077         }
1078 
1079         @Override public Iterator<Entry<K, V>> iterator() {
1080           return createEntryIterator();
1081         }
1082       };
1083     }
1084     return new Multimaps.Entries<K, V>() {
1085       @Override Multimap<K, V> multimap() {
1086         return AbstractMultimap.this;
1087       }
1088 
1089       @Override public Iterator<Entry<K, V>> iterator() {
1090         return createEntryIterator();
1091       }
1092     };
1093   }
1094 
1095   /**
1096    * Returns an iterator across all key-value map entries, used by {@code
1097    * entries().iterator()} and {@code values().iterator()}. The default
1098    * behavior, which traverses the values for one key, the values for a second
1099    * key, and so on, suffices for most {@code AbstractMultimap} implementations.
1100    *
1101    * @return an iterator across map entries
1102    */
1103   Iterator<Map.Entry<K, V>> createEntryIterator() {
1104     return new EntryIterator();
1105   }
1106 
1107   /** Iterator across all key-value pairs. */
1108   private class EntryIterator implements Iterator<Map.Entry<K, V>> {
1109     final Iterator<Map.Entry<K, Collection<V>>> keyIterator;
1110     K key;
1111     Collection<V> collection;
1112     Iterator<V> valueIterator;
1113 
1114     EntryIterator() {
1115       keyIterator = map.entrySet().iterator();
1116       if (keyIterator.hasNext()) {
1117         findValueIteratorAndKey();
1118       } else {
1119         valueIterator = Iterators.emptyModifiableIterator();
1120       }
1121     }
1122 
1123     void findValueIteratorAndKey() {
1124       Map.Entry<K, Collection<V>> entry = keyIterator.next();
1125       key = entry.getKey();
1126       collection = entry.getValue();
1127       valueIterator = collection.iterator();
1128     }
1129 
1130     @Override
1131     public boolean hasNext() {
1132       return keyIterator.hasNext() || valueIterator.hasNext();
1133     }
1134 
1135     @Override
1136     public Map.Entry<K, V> next() {
1137       if (!valueIterator.hasNext()) {
1138         findValueIteratorAndKey();
1139       }
1140       return Maps.immutableEntry(key, valueIterator.next());
1141     }
1142 
1143     @Override
1144     public void remove() {
1145       valueIterator.remove();
1146       if (collection.isEmpty()) {
1147         keyIterator.remove();
1148       }
1149       totalSize--;
1150     }
1151   }
1152 
1153   private transient Map<K, Collection<V>> asMap;
1154 
1155   @Override
1156   public Map<K, Collection<V>> asMap() {
1157     Map<K, Collection<V>> result = asMap;
1158     return (result == null) ? asMap = createAsMap() : result;
1159   }
1160 
1161   private Map<K, Collection<V>> createAsMap() {
1162     return (map instanceof SortedMap)
1163         ? new SortedAsMap((SortedMap<K, Collection<V>>) map) : new AsMap(map);
1164   }
1165 
1166   private class AsMap extends AbstractMap<K, Collection<V>> {
1167     /**
1168      * Usually the same as map, but smaller for the headMap(), tailMap(), or
1169      * subMap() of a SortedAsMap.
1170      */
1171     final transient Map<K, Collection<V>> submap;
1172 
1173     AsMap(Map<K, Collection<V>> submap) {
1174       this.submap = submap;
1175     }
1176 
1177     transient Set<Map.Entry<K, Collection<V>>> entrySet;
1178 
1179     @Override public Set<Map.Entry<K, Collection<V>>> entrySet() {
1180       Set<Map.Entry<K, Collection<V>>> result = entrySet;
1181       return (result == null) ? entrySet = new AsMapEntries() : result;
1182     }
1183 
1184     // The following methods are included for performance.
1185 
1186     @Override public boolean containsKey(Object key) {
1187       return Maps.safeContainsKey(submap, key);
1188     }
1189 
1190     @Override public Collection<V> get(Object key) {
1191       Collection<V> collection = Maps.safeGet(submap, key);
1192       if (collection == null) {
1193         return null;
1194       }
1195       @SuppressWarnings("unchecked")
1196       K k = (K) key;
1197       return wrapCollection(k, collection);
1198     }
1199 
1200     @Override public Set<K> keySet() {
1201       return AbstractMultimap.this.keySet();
1202     }
1203 
1204     @Override
1205     public int size() {
1206       return submap.size();
1207     }
1208 
1209     @Override public Collection<V> remove(Object key) {
1210       Collection<V> collection = submap.remove(key);
1211       if (collection == null) {
1212         return null;
1213       }
1214 
1215       Collection<V> output = createCollection();
1216       output.addAll(collection);
1217       totalSize -= collection.size();
1218       collection.clear();
1219       return output;
1220     }
1221 
1222     @Override public boolean equals(@Nullable Object object) {
1223       return this == object || submap.equals(object);
1224     }
1225 
1226     @Override public int hashCode() {
1227       return submap.hashCode();
1228     }
1229 
1230     @Override public String toString() {
1231       return submap.toString();
1232     }
1233 
1234     @Override
1235     public void clear() {
1236       if (submap == map) {
1237         AbstractMultimap.this.clear();
1238       } else {
1239 
1240         Iterators.clear(new AsMapIterator());
1241       }
1242     }
1243 
1244     class AsMapEntries extends Maps.EntrySet<K, Collection<V>> {
1245       @Override
1246       Map<K, Collection<V>> map() {
1247         return AsMap.this;
1248       }
1249 
1250       @Override public Iterator<Map.Entry<K, Collection<V>>> iterator() {
1251         return new AsMapIterator();
1252       }
1253 
1254       // The following methods are included for performance.
1255 
1256       @Override public boolean contains(Object o) {
1257         return Collections2.safeContains(submap.entrySet(), o);
1258       }
1259 
1260       @Override public boolean remove(Object o) {
1261         if (!contains(o)) {
1262           return false;
1263         }
1264         Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
1265         removeValuesForKey(entry.getKey());
1266         return true;
1267       }
1268     }
1269 
1270     /** Iterator across all keys and value collections. */
1271     class AsMapIterator implements Iterator<Map.Entry<K, Collection<V>>> {
1272       final Iterator<Map.Entry<K, Collection<V>>> delegateIterator
1273           = submap.entrySet().iterator();
1274       Collection<V> collection;
1275 
1276       @Override
1277       public boolean hasNext() {
1278         return delegateIterator.hasNext();
1279       }
1280 
1281       @Override
1282       public Map.Entry<K, Collection<V>> next() {
1283         Map.Entry<K, Collection<V>> entry = delegateIterator.next();
1284         K key = entry.getKey();
1285         collection = entry.getValue();
1286         return Maps.immutableEntry(key, wrapCollection(key, collection));
1287       }
1288 
1289       @Override
1290       public void remove() {
1291         delegateIterator.remove();
1292         totalSize -= collection.size();
1293         collection.clear();
1294       }
1295     }
1296   }
1297 
1298   private class SortedAsMap extends AsMap
1299       implements SortedMap<K, Collection<V>> {
1300     SortedAsMap(SortedMap<K, Collection<V>> submap) {
1301       super(submap);
1302     }
1303 
1304     SortedMap<K, Collection<V>> sortedMap() {
1305       return (SortedMap<K, Collection<V>>) submap;
1306     }
1307 
1308     @Override
1309     public Comparator<? super K> comparator() {
1310       return sortedMap().comparator();
1311     }
1312 
1313     @Override
1314     public K firstKey() {
1315       return sortedMap().firstKey();
1316     }
1317 
1318     @Override
1319     public K lastKey() {
1320       return sortedMap().lastKey();
1321     }
1322 
1323     @Override
1324     public SortedMap<K, Collection<V>> headMap(K toKey) {
1325       return new SortedAsMap(sortedMap().headMap(toKey));
1326     }
1327 
1328     @Override
1329     public SortedMap<K, Collection<V>> subMap(K fromKey, K toKey) {
1330       return new SortedAsMap(sortedMap().subMap(fromKey, toKey));
1331     }
1332 
1333     @Override
1334     public SortedMap<K, Collection<V>> tailMap(K fromKey) {
1335       return new SortedAsMap(sortedMap().tailMap(fromKey));
1336     }
1337 
1338     SortedSet<K> sortedKeySet;
1339 
1340     // returns a SortedSet, even though returning a Set would be sufficient to
1341     // satisfy the SortedMap.keySet() interface
1342     @Override public SortedSet<K> keySet() {
1343       SortedSet<K> result = sortedKeySet;
1344       return (result == null)
1345           ? sortedKeySet = new SortedKeySet(sortedMap()) : result;
1346     }
1347   }
1348 
1349   // Comparison and hashing
1350 
1351   @Override public boolean equals(@Nullable Object object) {
1352     if (object == this) {
1353       return true;
1354     }
1355     if (object instanceof Multimap) {
1356       Multimap<?, ?> that = (Multimap<?, ?>) object;
1357       return this.map.equals(that.asMap());
1358     }
1359     return false;
1360   }
1361 
1362   /**
1363    * Returns the hash code for this multimap.
1364    *
1365    * <p>The hash code of a multimap is defined as the hash code of the map view,
1366    * as returned by {@link Multimap#asMap}.
1367    *
1368    * @see Map#hashCode
1369    */
1370   @Override public int hashCode() {
1371     return map.hashCode();
1372   }
1373 
1374   /**
1375    * Returns a string representation of the multimap, generated by calling
1376    * {@code toString} on the map returned by {@link Multimap#asMap}.
1377    *
1378    * @return a string representation of the multimap
1379    */
1380   @Override
1381   public String toString() {
1382     return map.toString();
1383   }
1384 
1385   private static final long serialVersionUID = 2447537837011683357L;
1386 }
1387 
1388