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
17package com.google.common.collect;
18
19import static com.google.common.base.Preconditions.checkArgument;
20import static com.google.common.base.Preconditions.checkNotNull;
21import static com.google.common.base.Preconditions.checkState;
22
23import com.google.common.annotations.GwtCompatible;
24
25import java.io.Serializable;
26import java.util.AbstractCollection;
27import java.util.AbstractMap;
28import java.util.Collection;
29import java.util.Collections;
30import java.util.Comparator;
31import java.util.ConcurrentModificationException;
32import java.util.Iterator;
33import java.util.List;
34import java.util.ListIterator;
35import java.util.Map;
36import java.util.Map.Entry;
37import java.util.RandomAccess;
38import java.util.Set;
39import java.util.SortedMap;
40import java.util.SortedSet;
41
42import 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
88abstract 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   */
118  protected AbstractMultimap(Map<K, Collection<V>> map) {
119    checkArgument(map.isEmpty());
120    this.map = map;
121  }
122
123  /** Used during deserialization only. */
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   */
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   */
155  Collection<V> createCollection(@Nullable K key) {
156    return createCollection();
157  }
158
159  Map<K, Collection<V>> backingMap() {
160    return map;
161  }
162
163  // Query Operations
164
165  @Override
166  public int size() {
167    return totalSize;
168  }
169
170  @Override
171  public boolean isEmpty() {
172    return totalSize == 0;
173  }
174
175  @Override
176  public boolean containsKey(@Nullable Object key) {
177    return map.containsKey(key);
178  }
179
180  @Override
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
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
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
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
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
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
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
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
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
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
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
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   */
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
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
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     */
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     */
439    void removeIfEmpty() {
440      if (ancestor != null) {
441        ancestor.removeIfEmpty();
442      } else if (delegate.isEmpty()) {
443        map.remove(key);
444      }
445    }
446
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     */
458    void addToMap() {
459      if (ancestor != null) {
460        ancestor.addToMap();
461      } else {
462        map.put(key, delegate);
463      }
464    }
465
466    @Override public int size() {
467      refreshIfEmpty();
468      return delegate.size();
469    }
470
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
479    @Override public int hashCode() {
480      refreshIfEmpty();
481      return delegate.hashCode();
482    }
483
484    @Override public String toString() {
485      refreshIfEmpty();
486      return delegate.toString();
487    }
488
489    Collection<V> getDelegate() {
490      return delegate;
491    }
492
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
503      WrappedIterator() {
504        delegateIterator = iteratorOrListIterator(delegate);
505      }
506
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       */
515      void validateIterator() {
516        refreshIfEmpty();
517        if (delegate != originalDelegate) {
518          throw new ConcurrentModificationException();
519        }
520      }
521
522      @Override
523      public boolean hasNext() {
524        validateIterator();
525        return delegateIterator.hasNext();
526      }
527
528      @Override
529      public V next() {
530        validateIterator();
531        return delegateIterator.next();
532      }
533
534      @Override
535      public void remove() {
536        delegateIterator.remove();
537        totalSize--;
538        removeIfEmpty();
539      }
540
541      Iterator<V> getDelegateIterator() {
542        validateIterator();
543        return delegateIterator;
544      }
545    }
546
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
560    WrappedCollection getAncestor() {
561      return ancestor;
562    }
563
564    // The following methods are provided for better performance.
565
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
582    @Override public boolean contains(Object o) {
583      refreshIfEmpty();
584      return delegate.contains(o);
585    }
586
587    @Override public boolean containsAll(Collection<?> c) {
588      refreshIfEmpty();
589      return delegate.containsAll(c);
590    }
591
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
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
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
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
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> {
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> {
657    WrappedSortedSet(@Nullable K key, SortedSet<V> delegate,
658        @Nullable WrappedCollection ancestor) {
659      super(key, delegate, ancestor);
660    }
661
662    SortedSet<V> getSortedSetDelegate() {
663      return (SortedSet<V>) getDelegate();
664    }
665
666    @Override
667    public Comparator<? super V> comparator() {
668      return getSortedSetDelegate().comparator();
669    }
670
671    @Override
672    public V first() {
673      refreshIfEmpty();
674      return getSortedSetDelegate().first();
675    }
676
677    @Override
678    public V last() {
679      refreshIfEmpty();
680      return getSortedSetDelegate().last();
681    }
682
683    @Override
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
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
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> {
710    WrappedList(@Nullable K key, List<V> delegate,
711        @Nullable WrappedCollection ancestor) {
712      super(key, delegate, ancestor);
713    }
714
715    List<V> getListDelegate() {
716      return (List<V>) getDelegate();
717    }
718
719    @Override
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
737    public V get(int index) {
738      refreshIfEmpty();
739      return getListDelegate().get(index);
740    }
741
742    @Override
743    public V set(int index, V element) {
744      refreshIfEmpty();
745      return getListDelegate().set(index, element);
746    }
747
748    @Override
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
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
769    public int indexOf(Object o) {
770      refreshIfEmpty();
771      return getListDelegate().indexOf(o);
772    }
773
774    @Override
775    public int lastIndexOf(Object o) {
776      refreshIfEmpty();
777      return getListDelegate().lastIndexOf(o);
778    }
779
780    @Override
781    public ListIterator<V> listIterator() {
782      refreshIfEmpty();
783      return new WrappedListIterator();
784    }
785
786    @Override
787    public ListIterator<V> listIterator(int index) {
788      refreshIfEmpty();
789      return new WrappedListIterator(index);
790    }
791
792    @Override
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> {
803      WrappedListIterator() {}
804
805      public WrappedListIterator(int index) {
806        super(getListDelegate().listIterator(index));
807      }
808
809      private ListIterator<V> getDelegateListIterator() {
810        return (ListIterator<V>) getDelegateIterator();
811      }
812
813      @Override
814      public boolean hasPrevious() {
815        return getDelegateListIterator().hasPrevious();
816      }
817
818      @Override
819      public V previous() {
820        return getDelegateListIterator().previous();
821      }
822
823      @Override
824      public int nextIndex() {
825        return getDelegateListIterator().nextIndex();
826      }
827
828      @Override
829      public int previousIndex() {
830        return getDelegateListIterator().previousIndex();
831      }
832
833      @Override
834      public void set(V value) {
835        getDelegateListIterator().set(value);
836      }
837
838      @Override
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 {
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
865  public Set<K> keySet() {
866    Set<K> result = keySet;
867    return (result == null) ? keySet = createKeySet() : result;
868  }
869
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
883    KeySet(final Map<K, Collection<V>> subMap) {
884      this.subMap = subMap;
885    }
886
887    @Override
888    Map<K, Collection<V>> map() {
889      return subMap;
890    }
891
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
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
932    public void clear() {
933      Iterators.clear(iterator());
934    }
935
936    @Override public boolean containsAll(Collection<?> c) {
937      return subMap.keySet().containsAll(c);
938    }
939
940    @Override public boolean equals(@Nullable Object object) {
941      return this == object || this.subMap.keySet().equals(object);
942    }
943
944    @Override public int hashCode() {
945      return subMap.keySet().hashCode();
946    }
947  }
948
949  private class SortedKeySet extends KeySet implements SortedSet<K> {
950
951    SortedKeySet(SortedMap<K, Collection<V>> subMap) {
952      super(subMap);
953    }
954
955    SortedMap<K, Collection<V>> sortedMap() {
956      return (SortedMap<K, Collection<V>>) subMap;
957    }
958
959    @Override
960    public Comparator<? super K> comparator() {
961      return sortedMap().comparator();
962    }
963
964    @Override
965    public K first() {
966      return sortedMap().firstKey();
967    }
968
969    @Override
970    public SortedSet<K> headSet(K toElement) {
971      return new SortedKeySet(sortedMap().headMap(toElement));
972    }
973
974    @Override
975    public K last() {
976      return sortedMap().lastKey();
977    }
978
979    @Override
980    public SortedSet<K> subSet(K fromElement, K toElement) {
981      return new SortedKeySet(sortedMap().subMap(fromElement, toElement));
982    }
983
984    @Override
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
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