1090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2009 The Guava Authors
3090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
4090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License");
5090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * you may not use this file except in compliance with the License.
6090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * You may obtain a copy of the License at
7090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
8090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0
9090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
10090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Unless required by applicable law or agreed to in writing, software
11090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
12090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * See the License for the specific language governing permissions and
14090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * limitations under the License.
15090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */
16090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
17090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonpackage com.google.common.collect;
18090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
19090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport static com.google.common.base.Preconditions.checkNotNull;
20090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.Beta;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible;
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtIncompatible;
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
25090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.io.IOException;
26090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.io.InvalidObjectException;
27090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.io.ObjectInputStream;
28090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.io.ObjectOutputStream;
29090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.Arrays;
30090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.Collection;
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Comparator;
32090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.LinkedHashMap;
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map.Entry;
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.TreeMap;
35090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
36090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport javax.annotation.Nullable;
37090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
38090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/**
39090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * An immutable {@link SetMultimap} with reliable user-specified key and value
40090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * iteration order. Does not permit null keys or values.
41090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
42090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * <p>Unlike {@link Multimaps#unmodifiableSetMultimap(SetMultimap)}, which is
43090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * a <i>view</i> of a separate multimap which can still change, an instance of
44090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * {@code ImmutableSetMultimap} contains its own data and will <i>never</i>
45090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * change. {@code ImmutableSetMultimap} is convenient for
46090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * {@code public static final} multimaps ("constant multimaps") and also lets
47090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * you easily make a "defensive copy" of a multimap provided to your class by
48090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * a caller.
49090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> Although this class is not final, it cannot be subclassed as
51090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * it has no public or protected constructors. Thus, instances of this class
52090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * are guaranteed to be immutable.
53090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
54090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @author Mike Ward
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 2.0 (imported from Google Collections Library)
56090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible(serializable = true, emulated = true)
58090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonpublic class ImmutableSetMultimap<K, V>
59090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    extends ImmutableMultimap<K, V>
60090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    implements SetMultimap<K, V> {
61090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
62090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /** Returns the empty multimap. */
63090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  // Casting is safe because the multimap will never hold any elements.
64090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  @SuppressWarnings("unchecked")
65090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <K, V> ImmutableSetMultimap<K, V> of() {
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return (ImmutableSetMultimap<K, V>) EmptyImmutableSetMultimap.INSTANCE;
67090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
68090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
69090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
70090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Returns an immutable multimap containing a single entry.
71090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
72090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <K, V> ImmutableSetMultimap<K, V> of(K k1, V v1) {
73090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    ImmutableSetMultimap.Builder<K, V> builder = ImmutableSetMultimap.builder();
74090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    builder.put(k1, v1);
75090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return builder.build();
76090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
77090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
78090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
79090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Returns an immutable multimap containing the given entries, in order.
80090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Repeated occurrences of an entry (according to {@link Object#equals}) after
81090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * the first are ignored.
82090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
83090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <K, V> ImmutableSetMultimap<K, V> of(K k1, V v1, K k2, V v2) {
84090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    ImmutableSetMultimap.Builder<K, V> builder = ImmutableSetMultimap.builder();
85090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    builder.put(k1, v1);
86090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    builder.put(k2, v2);
87090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return builder.build();
88090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
89090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
90090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
91090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Returns an immutable multimap containing the given entries, in order.
92090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Repeated occurrences of an entry (according to {@link Object#equals}) after
93090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * the first are ignored.
94090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
95090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <K, V> ImmutableSetMultimap<K, V> of(
96090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      K k1, V v1, K k2, V v2, K k3, V v3) {
97090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    ImmutableSetMultimap.Builder<K, V> builder = ImmutableSetMultimap.builder();
98090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    builder.put(k1, v1);
99090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    builder.put(k2, v2);
100090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    builder.put(k3, v3);
101090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return builder.build();
102090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
103090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
104090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
105090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Returns an immutable multimap containing the given entries, in order.
106090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Repeated occurrences of an entry (according to {@link Object#equals}) after
107090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * the first are ignored.
108090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
109090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <K, V> ImmutableSetMultimap<K, V> of(
110090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
111090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    ImmutableSetMultimap.Builder<K, V> builder = ImmutableSetMultimap.builder();
112090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    builder.put(k1, v1);
113090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    builder.put(k2, v2);
114090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    builder.put(k3, v3);
115090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    builder.put(k4, v4);
116090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return builder.build();
117090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
118090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
119090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
120090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Returns an immutable multimap containing the given entries, in order.
121090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Repeated occurrences of an entry (according to {@link Object#equals}) after
122090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * the first are ignored.
123090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
124090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <K, V> ImmutableSetMultimap<K, V> of(
125090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
126090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    ImmutableSetMultimap.Builder<K, V> builder = ImmutableSetMultimap.builder();
127090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    builder.put(k1, v1);
128090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    builder.put(k2, v2);
129090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    builder.put(k3, v3);
130090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    builder.put(k4, v4);
131090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    builder.put(k5, v5);
132090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return builder.build();
133090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
134090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
135090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  // looking for of() with > 5 entries? Use the builder instead.
136090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
137090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
138090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Returns a new {@link Builder}.
139090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
140090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <K, V> Builder<K, V> builder() {
141090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return new Builder<K, V>();
142090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
143090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
144090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
145090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Multimap for {@link ImmutableSetMultimap.Builder} that maintains key
146090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * and value orderings and performs better than {@link LinkedHashMultimap}.
147090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
148090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private static class BuilderMultimap<K, V> extends AbstractMultimap<K, V> {
149090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    BuilderMultimap() {
150090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      super(new LinkedHashMap<K, Collection<V>>());
151090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
152090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override Collection<V> createCollection() {
153090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      return Sets.newLinkedHashSet();
154090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
155090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    private static final long serialVersionUID = 0;
156090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
157090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
158090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Multimap for {@link ImmutableSetMultimap.Builder} that sorts keys and
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * maintains value orderings.
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class SortedKeyBuilderMultimap<K, V>
1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      extends AbstractMultimap<K, V> {
1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedKeyBuilderMultimap(
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Comparator<? super K> keyComparator, Multimap<K, V> multimap) {
1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      super(new TreeMap<K, Collection<V>>(keyComparator));
1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      putAll(multimap);
1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override Collection<V> createCollection() {
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Sets.newLinkedHashSet();
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private static final long serialVersionUID = 0;
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
176090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * A builder for creating immutable {@code SetMultimap} instances, especially
177090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * {@code public static final} multimaps ("constant multimaps"). Example:
178090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * <pre>   {@code
179090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
180090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *   static final Multimap<String, Integer> STRING_TO_INTEGER_MULTIMAP =
181090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *       new ImmutableSetMultimap.Builder<String, Integer>()
182090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *           .put("one", 1)
183090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *           .putAll("several", 1, 2, 3)
184090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *           .putAll("many", 1, 2, 3, 4, 5)
185090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *           .build();}</pre>
186090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Builder instances can be reused; it is safe to call {@link #build} multiple
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * times to build multiple multimaps in series. Each multimap contains the
1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * key-value mappings in the previously created multimaps.
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 2.0 (imported from Google Collections Library)
192090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
193090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static final class Builder<K, V>
194090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      extends ImmutableMultimap.Builder<K, V> {
195090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    /**
196090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * Creates a new builder. The returned builder is equivalent to the builder
197090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * generated by {@link ImmutableSetMultimap#builder}.
198090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     */
1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Builder() {
2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      builderMultimap = new BuilderMultimap<K, V>();
2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
202090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
203090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    /**
204090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * Adds a key-value mapping to the built multimap if it is not already
205090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * present.
206090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     */
207090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public Builder<K, V> put(K key, V value) {
208090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      builderMultimap.put(checkNotNull(key), checkNotNull(value));
209090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      return this;
210090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
211090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
212090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    /**
2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * Adds an entry to the built multimap if it is not already present.
214090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     *
2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * @since 11.0
216090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     */
2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Builder<K, V> put(Entry<? extends K, ? extends V> entry) {
2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      builderMultimap.put(
2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          checkNotNull(entry.getKey()), checkNotNull(entry.getValue()));
2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return this;
2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
223090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public Builder<K, V> putAll(K key, Iterable<? extends V> values) {
224090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      Collection<V> collection = builderMultimap.get(checkNotNull(key));
225090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      for (V value : values) {
226090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        collection.add(checkNotNull(value));
227090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      }
228090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      return this;
229090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
230090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
231090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public Builder<K, V> putAll(K key, V... values) {
232090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      return putAll(key, Arrays.asList(values));
233090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
234090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
235090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public Builder<K, V> putAll(
236090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        Multimap<? extends K, ? extends V> multimap) {
2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (Entry<? extends K, ? extends Collection<? extends V>> entry
238090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          : multimap.asMap().entrySet()) {
239090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        putAll(entry.getKey(), entry.getValue());
240090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      }
241090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      return this;
242090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
243090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
244090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    /**
2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * {@inheritDoc}
2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     *
2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * @since 8.0
2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     */
2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Beta @Override
2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Builder<K, V> orderKeysBy(Comparator<? super K> keyComparator) {
2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      builderMultimap = new SortedKeyBuilderMultimap<K, V>(
2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          checkNotNull(keyComparator), builderMultimap);
2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return this;
2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /**
2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * Specifies the ordering of the generated multimap's values for each key.
2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     *
2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * <p>If this method is called, the sets returned by the {@code get()}
2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * method of the generated multimap and its {@link Multimap#asMap()} view
2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * are {@link ImmutableSortedSet} instances. However, serialization does not
2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * preserve that property, though it does maintain the key and value
2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * ordering.
2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     *
2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * @since 8.0
2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     */
2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // TODO: Make serialization behavior consistent.
2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Beta @Override
2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Builder<K, V> orderValuesBy(Comparator<? super V> valueComparator) {
2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      super.orderValuesBy(valueComparator);
2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return this;
2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /**
275090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * Returns a newly-created immutable set multimap.
276090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     */
277090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public ImmutableSetMultimap<K, V> build() {
2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return copyOf(builderMultimap, valueComparator);
279090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
280090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
281090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
282090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
283090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Returns an immutable set multimap containing the same mappings as
284090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * {@code multimap}. The generated multimap's key and value orderings
285090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * correspond to the iteration ordering of the {@code multimap.asMap()} view.
286090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Repeated occurrences of an entry in the multimap after the first are
287090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * ignored.
288090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Despite the method name, this method attempts to avoid actually copying
2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the data when it is safe to do so. The exact circumstances under which a
2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * copy will or will not be performed are undocumented and subject to change.
292090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
293090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws NullPointerException if any key or value in {@code multimap} is
294090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *     null
295090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
296090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <K, V> ImmutableSetMultimap<K, V> copyOf(
297090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      Multimap<? extends K, ? extends V> multimap) {
2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return copyOf(multimap, null);
2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static <K, V> ImmutableSetMultimap<K, V> copyOf(
3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Multimap<? extends K, ? extends V> multimap,
3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Comparator<? super V> valueComparator) {
3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkNotNull(multimap); // eager for GWT
3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (multimap.isEmpty() && valueComparator == null) {
306090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      return of();
307090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
308090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
309090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    if (multimap instanceof ImmutableSetMultimap) {
310090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      @SuppressWarnings("unchecked") // safe since multimap is not writable
311090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      ImmutableSetMultimap<K, V> kvMultimap
312090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          = (ImmutableSetMultimap<K, V>) multimap;
3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (!kvMultimap.isPartialView()) {
3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return kvMultimap;
3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
316090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
317090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
318090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    ImmutableMap.Builder<K, ImmutableSet<V>> builder = ImmutableMap.builder();
319090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    int size = 0;
320090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (Entry<? extends K, ? extends Collection<? extends V>> entry
322090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        : multimap.asMap().entrySet()) {
323090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      K key = entry.getKey();
324090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      Collection<? extends V> values = entry.getValue();
3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      ImmutableSet<V> set = (valueComparator == null)
3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          ? ImmutableSet.copyOf(values)
3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          : ImmutableSortedSet.copyOf(valueComparator, values);
328090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      if (!set.isEmpty()) {
329090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        builder.put(key, set);
330090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        size += set.size();
331090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      }
332090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
333090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new ImmutableSetMultimap<K, V>(
3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        builder.build(), size, valueComparator);
336090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
337090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // Returned by get() when values are sorted and a missing key is provided.
3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private final transient ImmutableSortedSet<V> emptySet;
3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  ImmutableSetMultimap(ImmutableMap<K, ImmutableSet<V>> map, int size,
3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Nullable Comparator<? super V> valueComparator) {
343090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    super(map, size);
3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    this.emptySet = (valueComparator == null)
3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ? null : ImmutableSortedSet.<V>emptySet(valueComparator);
346090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
347090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
348090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  // views
349090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
350090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
351090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Returns an immutable set of the values for the given key.  If no mappings
352090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * in the multimap have the provided key, an empty immutable set is returned.
353090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * The values are in the same order as the parameters used to build this
354090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * multimap.
355090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
356090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  @Override public ImmutableSet<V> get(@Nullable K key) {
357090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    // This cast is safe as its type is known in constructor.
358090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    ImmutableSet<V> set = (ImmutableSet<V>) map.get(key);
3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (set != null) {
3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return set;
3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } else if (emptySet != null) {
3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return emptySet;
3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } else {
3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return ImmutableSet.<V>of();
3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private transient ImmutableSetMultimap<V, K> inverse;
3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@inheritDoc}
3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Because an inverse of a set multimap cannot contain multiple pairs with the same key and
3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * value, this method returns an {@code ImmutableSetMultimap} rather than the
3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code ImmutableMultimap} specified in the {@code ImmutableMultimap} class.
3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 11
3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Beta
3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public ImmutableSetMultimap<V, K> inverse() {
3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    ImmutableSetMultimap<V, K> result = inverse;
3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return (result == null) ? (inverse = invert()) : result;
3831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private ImmutableSetMultimap<V, K> invert() {
3861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Builder<V, K> builder = builder();
3871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (Entry<K, V> entry : entries()) {
3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      builder.put(entry.getValue(), entry.getKey());
3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    ImmutableSetMultimap<V, K> invertedMultimap = builder.build();
3911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    invertedMultimap.inverse = this;
3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return invertedMultimap;
393090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
394090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
395090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
396090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Guaranteed to throw an exception and leave the multimap unmodified.
397090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
398090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws UnsupportedOperationException always
399090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
400090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  @Override public ImmutableSet<V> removeAll(Object key) {
401090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    throw new UnsupportedOperationException();
402090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
403090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
404090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
405090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Guaranteed to throw an exception and leave the multimap unmodified.
406090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
407090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws UnsupportedOperationException always
408090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
409090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  @Override public ImmutableSet<V> replaceValues(
410090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      K key, Iterable<? extends V> values) {
411090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    throw new UnsupportedOperationException();
412090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
413090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private transient ImmutableSet<Entry<K, V>> entries;
415090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
416090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
417090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Returns an immutable collection of all key-value pairs in the multimap.
418090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Its iterator traverses the values for the first key, the values for the
419090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * second key, and so on.
420090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
4211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // TODO(kevinb): Fix this so that two copies of the entries are not created.
4221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public ImmutableSet<Entry<K, V>> entries() {
4231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    ImmutableSet<Entry<K, V>> result = entries;
424090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return (result == null)
425090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        ? (entries = ImmutableSet.copyOf(super.entries()))
426090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        : result;
427090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
428090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
429090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
430090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @serialData number of distinct keys, and then for each distinct key: the
431090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *     key, the number of values for that key, and the key's values
432090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
4331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("java.io.ObjectOutputStream")
434090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private void writeObject(ObjectOutputStream stream) throws IOException {
435090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    stream.defaultWriteObject();
436090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    Serialization.writeMultimap(this, stream);
437090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
438090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("java.io.ObjectInputStream")
440090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private void readObject(ObjectInputStream stream)
441090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      throws IOException, ClassNotFoundException {
442090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    stream.defaultReadObject();
443090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    int keyCount = stream.readInt();
444090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    if (keyCount < 0) {
445090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      throw new InvalidObjectException("Invalid key count " + keyCount);
446090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
447090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    ImmutableMap.Builder<Object, ImmutableSet<Object>> builder
448090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        = ImmutableMap.builder();
449090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    int tmpSize = 0;
450090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
451090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    for (int i = 0; i < keyCount; i++) {
452090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      Object key = stream.readObject();
453090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      int valueCount = stream.readInt();
454090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      if (valueCount <= 0) {
455090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        throw new InvalidObjectException("Invalid value count " + valueCount);
456090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      }
457090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
458090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      Object[] array = new Object[valueCount];
459090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      for (int j = 0; j < valueCount; j++) {
460090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        array[j] = stream.readObject();
461090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      }
4621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      ImmutableSet<Object> valueSet = ImmutableSet.copyOf(array);
463090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      if (valueSet.size() != array.length) {
464090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        throw new InvalidObjectException(
465090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson            "Duplicate key-value pairs exist for key " + key);
466090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      }
467090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      builder.put(key, valueSet);
468090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      tmpSize += valueCount;
469090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
470090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
471090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    ImmutableMap<Object, ImmutableSet<Object>> tmpMap;
472090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    try {
473090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      tmpMap = builder.build();
474090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    } catch (IllegalArgumentException e) {
475090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      throw (InvalidObjectException)
476090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          new InvalidObjectException(e.getMessage()).initCause(e);
477090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
478090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
479090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    FieldSettersHolder.MAP_FIELD_SETTER.set(this, tmpMap);
480090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    FieldSettersHolder.SIZE_FIELD_SETTER.set(this, tmpSize);
481090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
482090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
4831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("not needed in emulated source.")
484090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private static final long serialVersionUID = 0;
485090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson}
486