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   * Implementation of {@link BidiMap} that uses 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   *
44   * @since 3.0
45   */
46  public class DualHashBidiMap<K, V> extends AbstractDualBidiMap<K, V> implements Serializable {
47  
48      /** Ensure serialization compatibility */
49      private static final long serialVersionUID = 721969328361808L;
50  
51      /**
52       * Creates an empty {@code HashBidiMap}.
53       */
54      public DualHashBidiMap() {
55          super(new HashMap<>(), new HashMap<>());
56      }
57  
58      /**
59       * Constructs a {@code HashBidiMap} and copies the mappings from
60       * specified {@code Map}.
61       *
62       * @param map  the map whose mappings are to be placed in this map
63       */
64      public DualHashBidiMap(final Map<? extends K, ? extends V> map) {
65          super(new HashMap<>(), new HashMap<>());
66          putAll(map);
67      }
68  
69      /**
70       * Constructs a {@code HashBidiMap} that decorates the specified maps.
71       *
72       * @param normalMap  the normal direction map
73       * @param reverseMap  the reverse direction map
74       * @param inverseBidiMap  the inverse BidiMap
75       */
76      protected DualHashBidiMap(final Map<K, V> normalMap, final Map<V, K> reverseMap,
77                                final BidiMap<V, K> inverseBidiMap) {
78          super(normalMap, reverseMap, inverseBidiMap);
79      }
80  
81      /**
82       * Creates a new instance of this object.
83       *
84       * @param normalMap  the normal direction map
85       * @param reverseMap  the reverse direction map
86       * @param inverseBidiMap  the inverse BidiMap
87       * @return new bidi map
88       */
89      @Override
90      protected BidiMap<V, K> createBidiMap(final Map<V, K> normalMap, final Map<K, V> reverseMap,
91                                            final BidiMap<K, V> inverseBidiMap) {
92          return new DualHashBidiMap<>(normalMap, reverseMap, inverseBidiMap);
93      }
94  
95      private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
96          in.defaultReadObject();
97          normalMap = new HashMap<>();
98          reverseMap = new HashMap<>();
99          @SuppressWarnings("unchecked") // will fail at runtime if stream is incorrect
100         final Map<K, V> map = (Map<K, V>) in.readObject();
101         putAll(map);
102     }
103 
104     // Serialization
105     private void writeObject(final ObjectOutputStream out) throws IOException {
106         out.defaultWriteObject();
107         out.writeObject(normalMap);
108     }
109 
110 }