1090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 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
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkArgument;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
21090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport com.google.common.annotations.GwtCompatible;
22090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport com.google.common.annotations.VisibleForTesting;
23090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
24090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.ArrayList;
25090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.Collection;
26090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.HashMap;
27090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.List;
28bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
29090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/**
30090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Implementation of {@code Multimap} that uses an {@code ArrayList} to store
31090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * the values for a given key. A {@link HashMap} associates each key with an
32090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * {@link ArrayList} of values.
33090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
34090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * <p>When iterating through the collections supplied by this class, the
35090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * ordering of values for a given key agrees with the order in which the values
36090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * were added.
37090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
38090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * <p>This multimap allows duplicate key-value pairs. After adding a new
39090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * key-value pair equal to an existing key-value pair, the {@code
40090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * ArrayListMultimap} will contain entries for both the new value and the old
41090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * value.
42090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
43090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * <p>Keys and values may be null. All optional multimap methods are supported,
44090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * and all returned views are modifiable.
45090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
46090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * <p>The lists returned by {@link #get}, {@link #removeAll}, and {@link
47090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * #replaceValues} all implement {@link java.util.RandomAccess}.
48090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
49090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * <p>This class is not threadsafe when any concurrent operations update the
50090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * multimap. Concurrent read operations will work correctly. To allow concurrent
51090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * update operations, wrap your multimap with a call to {@link
52090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Multimaps#synchronizedListMultimap}.
53090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
54090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @author Jared Levy
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 2.0 (imported from Google Collections Library)
56090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible(serializable = true, emulated = true)
58090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonpublic final class ArrayListMultimap<K, V> extends AbstractListMultimap<K, V> {
59090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  // Default from ArrayList
60090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private static final int DEFAULT_VALUES_PER_KEY = 10;
61090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
62090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  @VisibleForTesting transient int expectedValuesPerKey;
63090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
64090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
65090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Creates a new, empty {@code ArrayListMultimap} with the default initial
66090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * capacities.
67090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
68090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <K, V> ArrayListMultimap<K, V> create() {
69090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return new ArrayListMultimap<K, V>();
70090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
71090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
72090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
73090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Constructs an empty {@code ArrayListMultimap} with enough capacity to hold
74090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * the specified numbers of keys and values without resizing.
75090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
76090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @param expectedKeys the expected number of distinct keys
77090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @param expectedValuesPerKey the expected average number of values per key
78090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws IllegalArgumentException if {@code expectedKeys} or {@code
79090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *      expectedValuesPerKey} is negative
80090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
81090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <K, V> ArrayListMultimap<K, V> create(
82090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      int expectedKeys, int expectedValuesPerKey) {
83090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return new ArrayListMultimap<K, V>(expectedKeys, expectedValuesPerKey);
84090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
85090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
86090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
87090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Constructs an {@code ArrayListMultimap} with the same mappings as the
88090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * specified multimap.
89090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
90090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @param multimap the multimap whose contents are copied to this multimap
91090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
92090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <K, V> ArrayListMultimap<K, V> create(
93090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      Multimap<? extends K, ? extends V> multimap) {
94090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return new ArrayListMultimap<K, V>(multimap);
95090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
96090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
97090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private ArrayListMultimap() {
98090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    super(new HashMap<K, Collection<V>>());
99090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    expectedValuesPerKey = DEFAULT_VALUES_PER_KEY;
100090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
101090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
102090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private ArrayListMultimap(int expectedKeys, int expectedValuesPerKey) {
103090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    super(Maps.<K, Collection<V>>newHashMapWithExpectedSize(expectedKeys));
104090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    checkArgument(expectedValuesPerKey >= 0);
105090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    this.expectedValuesPerKey = expectedValuesPerKey;
106090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
107090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
108090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private ArrayListMultimap(Multimap<? extends K, ? extends V> multimap) {
109090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    this(multimap.keySet().size(),
110090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        (multimap instanceof ArrayListMultimap) ?
111090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson            ((ArrayListMultimap<?, ?>) multimap).expectedValuesPerKey :
112090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson            DEFAULT_VALUES_PER_KEY);
113090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    putAll(multimap);
114090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
115090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
116090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
117090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Creates a new, empty {@code ArrayList} to hold the collection of values for
118090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * an arbitrary key.
119090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
120090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  @Override List<V> createCollection() {
121090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return new ArrayList<V>(expectedValuesPerKey);
122090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
123090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
124090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
125090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Reduces the memory used by this {@code ArrayListMultimap}, if feasible.
126090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
127090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public void trimToSize() {
128090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    for (Collection<V> collection : backingMap().values()) {
129090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      ArrayList<V> arrayList = (ArrayList<V>) collection;
130090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      arrayList.trimToSize();
131090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
132090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
133090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson}
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
135