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.HashMap;
24  import java.util.HashSet;
25  import java.util.Map;
26  
27  import org.apache.commons.collections4.MultiValuedMap;
28  
29  /**
30   * Implements a {@code SetValuedMap}, using a {@link HashMap} to provide data
31   * storage and {@link HashSet}s as value collections. This is the standard
32   * implementation of a SetValuedMap.
33   * <p>
34   * <strong>Note that HashSetValuedHashMap is not synchronized and is not
35   * thread-safe.</strong> If you wish to use this map from multiple threads
36   * concurrently, you must use appropriate synchronization. This class may throw
37   * exceptions when accessed by concurrent threads without synchronization.
38   * </p>
39   *
40   * @param <K> the type of the keys in this map
41   * @param <V> the type of the values in this map
42   * @since 4.1
43   */
44  public class HashSetValuedHashMap<K, V> extends AbstractSetValuedMap<K, V>
45      implements Serializable {
46  
47      /** Serialization Version */
48      private static final long serialVersionUID = 20151118L;
49  
50      /**
51       * The initial map capacity used when none specified in constructor.
52       */
53      private static final int DEFAULT_INITIAL_MAP_CAPACITY = 16;
54  
55      /**
56       * The initial set capacity when using none specified in constructor.
57       */
58      private static final int DEFAULT_INITIAL_SET_CAPACITY = 3;
59  
60      /**
61       * The initial list capacity when creating a new value collection.
62       */
63      private final int initialSetCapacity;
64  
65      /**
66       * Creates an empty HashSetValuedHashMap with the default initial
67       * map capacity (16) and the default initial set capacity (3).
68       */
69      public HashSetValuedHashMap() {
70          this(DEFAULT_INITIAL_MAP_CAPACITY, DEFAULT_INITIAL_SET_CAPACITY);
71      }
72  
73      /**
74       * Creates an empty HashSetValuedHashMap with the default initial
75       * map capacity (16) and the specified initial set capacity.
76       *
77       * @param initialSetCapacity  the initial capacity used for value collections
78       */
79      public HashSetValuedHashMap(final int initialSetCapacity) {
80          this(DEFAULT_INITIAL_MAP_CAPACITY, initialSetCapacity);
81      }
82  
83      /**
84       * Creates an empty HashSetValuedHashMap with the specified initial
85       * map and list capacities.
86       *
87       * @param initialMapCapacity  the initial hashmap capacity
88       * @param initialSetCapacity  the initial capacity used for value collections
89       */
90      public HashSetValuedHashMap(final int initialMapCapacity, final int initialSetCapacity) {
91          super(new HashMap<>(initialMapCapacity));
92          this.initialSetCapacity = initialSetCapacity;
93      }
94  
95      /**
96       * Creates an HashSetValuedHashMap copying all the mappings of the given map.
97       *
98       * @param map a {@code Map} to copy into this map
99       */
100     public HashSetValuedHashMap(final Map<? extends K, ? extends V> map) {
101         this(map.size(), DEFAULT_INITIAL_SET_CAPACITY);
102         super.putAll(map);
103     }
104 
105     /**
106      * Creates an HashSetValuedHashMap copying all the mappings of the given map.
107      *
108      * @param map a {@code MultiValuedMap} to copy into this map
109      */
110     public HashSetValuedHashMap(final MultiValuedMap<? extends K, ? extends V> map) {
111         this(map.size(), DEFAULT_INITIAL_SET_CAPACITY);
112         super.putAll(map);
113     }
114 
115     @Override
116     protected HashSet<V> createCollection() {
117         return new HashSet<>(initialSetCapacity);
118     }
119 
120     private void readObject(final ObjectInputStream ois) throws IOException, ClassNotFoundException {
121         ois.defaultReadObject();
122         setMap(new HashMap<>());
123         doReadObject(ois);
124     }
125 
126     private void writeObject(final ObjectOutputStream oos) throws IOException {
127         oos.defaultWriteObject();
128         doWriteObject(oos);
129     }
130 
131 }