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