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.bidimap;
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.Map;
25  
26  import org.apache.commons.collections4.BidiMap;
27  
28  /**
29   * Implements {@link BidiMap} with two {@link HashMap} instances.
30   * <p>
31   * Two {@link HashMap} instances are used in this class.
32   * This provides fast lookups at the expense of storing two sets of map entries.
33   * Commons Collections would welcome the addition of a direct hash-based
34   * implementation of the {@link BidiMap} interface.
35   * </p>
36   * <p>
37   * NOTE: From Commons Collections 3.1, all subclasses will use {@link HashMap}
38   * and the flawed {@code createMap} method is ignored.
39   * </p>
40   *
41   * @param <K> the type of the keys in the map
42   * @param <V> the type of the values in the map
43   * @since 3.0
44   */
45  public class DualHashBidiMap<K, V> extends AbstractDualBidiMap<K, V> implements Serializable {
46  
47      /** Ensure serialization compatibility */
48      private static final long serialVersionUID = 721969328361808L;
49  
50      /**
51       * Creates an empty {@code HashBidiMap}.
52       */
53      public DualHashBidiMap() {
54          super(new HashMap<>(), new HashMap<>());
55      }
56  
57      /**
58       * Constructs a {@code HashBidiMap} and copies the mappings from
59       * specified {@code Map}.
60       *
61       * @param map  the map whose mappings are to be placed in this map
62       */
63      public DualHashBidiMap(final Map<? extends K, ? extends V> map) {
64          super(new HashMap<>(), new HashMap<>());
65          putAll(map);
66      }
67  
68      /**
69       * Constructs a {@code HashBidiMap} that decorates the specified maps.
70       *
71       * @param normalMap  the normal direction map
72       * @param reverseMap  the reverse direction map
73       * @param inverseBidiMap  the inverse BidiMap
74       */
75      protected DualHashBidiMap(final Map<K, V> normalMap, final Map<V, K> reverseMap,
76                                final BidiMap<V, K> inverseBidiMap) {
77          super(normalMap, reverseMap, inverseBidiMap);
78      }
79  
80      /**
81       * Creates a new instance of this object.
82       *
83       * @param normalMap  the normal direction map
84       * @param reverseMap  the reverse direction map
85       * @param inverseBidiMap  the inverse BidiMap
86       * @return new bidi map
87       */
88      @Override
89      protected BidiMap<V, K> createBidiMap(final Map<V, K> normalMap, final Map<K, V> reverseMap,
90                                            final BidiMap<K, V> inverseBidiMap) {
91          return new DualHashBidiMap<>(normalMap, reverseMap, inverseBidiMap);
92      }
93  
94      /**
95       * Deserializes an instance from an ObjectInputStream.
96       *
97       * @param in The source ObjectInputStream.
98       * @throws IOException            Any of the usual Input/Output related exceptions.
99       * @throws ClassNotFoundException A class of a serialized object cannot be found.
100      */
101     private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
102         in.defaultReadObject();
103         normalMap = new HashMap<>();
104         reverseMap = new HashMap<>();
105         @SuppressWarnings("unchecked") // will fail at runtime if stream is incorrect
106         final Map<K, V> map = (Map<K, V>) in.readObject();
107         putAll(map);
108     }
109 
110     /**
111      * Serializes this object to an ObjectOutputStream.
112      *
113      * @param out the target ObjectOutputStream.
114      * @throws IOException thrown when an I/O errors occur writing to the target stream.
115      */
116     private void writeObject(final ObjectOutputStream out) throws IOException {
117         out.defaultWriteObject();
118         out.writeObject(normalMap);
119     }
120 
121 }