View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.collections4.multimap;
18  
19  import java.io.IOException;
20  import java.io.ObjectInputStream;
21  import java.io.ObjectOutputStream;
22  import java.io.Serializable;
23  import java.util.ArrayList;
24  import java.util.Collection;
25  import java.util.HashMap;
26  import java.util.Map;
27  
28  import org.apache.commons.collections4.MultiValuedMap;
29  
30  /**
31   * Implements a {@code ListValuedMap}, using a {@link HashMap} to provide data
32   * storage and {@link ArrayList}s as value collections. This is the standard
33   * implementation of a ListValuedMap.
34   * <p>
35   * <strong>Note that ArrayListValuedHashMap is not synchronized and is not
36   * thread-safe.</strong> If you wish to use this map from multiple threads
37   * concurrently, you must use appropriate synchronization. This class may throw
38   * exceptions when accessed by concurrent threads without synchronization.
39   * </p>
40   *
41   * @param <K> the type of the keys in this map
42   * @param <V> the type of the values in this map
43   * @since 4.1
44   */
45  public class ArrayListValuedHashMap<K, V> extends AbstractListValuedMap<K, V>
46      implements Serializable {
47  
48      /** Serialization Version */
49      private static final long serialVersionUID = 20151118L;
50  
51      /**
52       * The initial map capacity used when none specified in constructor.
53       */
54      private static final int DEFAULT_INITIAL_MAP_CAPACITY = 16;
55  
56      /**
57       * The initial list capacity when using none specified in constructor.
58       */
59      private static final int DEFAULT_INITIAL_LIST_CAPACITY = 3;
60  
61      /**
62       * The initial list capacity when creating a new value collection.
63       */
64      private final int initialListCapacity;
65  
66      /**
67       * Creates an empty ArrayListValuedHashMap with the default initial
68       * map capacity (16) and the default initial list capacity (3).
69       */
70      public ArrayListValuedHashMap() {
71          this(DEFAULT_INITIAL_MAP_CAPACITY, DEFAULT_INITIAL_LIST_CAPACITY);
72      }
73  
74      /**
75       * Creates an empty ArrayListValuedHashMap with the default initial
76       * map capacity (16) and the specified initial list capacity.
77       *
78       * @param initialListCapacity  the initial capacity used for value collections
79       */
80      public ArrayListValuedHashMap(final int initialListCapacity) {
81          this(DEFAULT_INITIAL_MAP_CAPACITY, initialListCapacity);
82      }
83  
84      /**
85       * Creates an empty ArrayListValuedHashMap with the specified initial
86       * map and list capacities.
87       *
88       * @param initialMapCapacity  the initial hashmap capacity
89       * @param initialListCapacity  the initial capacity used for value collections
90       */
91      public ArrayListValuedHashMap(final int initialMapCapacity, final int initialListCapacity) {
92          super(new HashMap<>(initialMapCapacity));
93          this.initialListCapacity = initialListCapacity;
94      }
95  
96      /**
97       * Creates an ArrayListValuedHashMap copying all the mappings of the given map.
98       *
99       * @param map a {@code Map} to copy into this map
100      */
101     public ArrayListValuedHashMap(final Map<? extends K, ? extends V> map) {
102         this(map.size(), DEFAULT_INITIAL_LIST_CAPACITY);
103         super.putAll(map);
104     }
105 
106     /**
107      * Creates an ArrayListValuedHashMap copying all the mappings of the given map.
108      *
109      * @param map a {@code MultiValuedMap} to copy into this map
110      */
111     public ArrayListValuedHashMap(final MultiValuedMap<? extends K, ? extends V> map) {
112         this(map.size(), DEFAULT_INITIAL_LIST_CAPACITY);
113         super.putAll(map);
114     }
115 
116     @Override
117     protected ArrayList<V> createCollection() {
118         return new ArrayList<>(initialListCapacity);
119     }
120 
121     private void readObject(final ObjectInputStream ois) throws IOException, ClassNotFoundException {
122         ois.defaultReadObject();
123         setMap(new HashMap<>());
124         doReadObject(ois);
125     }
126 
127     /**
128      * Trims the capacity of all value collections to their current size.
129      */
130     public void trimToSize() {
131         for (final Collection<V> coll : getMap().values()) {
132             final ArrayList<V> list = (ArrayList<V>) coll;
133             list.trimToSize();
134         }
135     }
136 
137     private void writeObject(final ObjectOutputStream oos) throws IOException {
138         oos.defaultWriteObject();
139         doWriteObject(oos);
140     }
141 
142 }