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.LinkedHashMap;
24  import java.util.Map;
25  
26  import org.apache.commons.collections4.BidiMap;
27  
28  /**
29   * Implements {@link BidiMap} with two {@link LinkedHashMap} instances.
30   * <p>
31   * Two {@link LinkedHashMap} instances are used in this class.
32   * This provides fast lookups at the expense of storing two sets of map entries and two linked lists.
33   * </p>
34   *
35   * @param <K> the type of the keys in the map
36   * @param <V> the type of the values in the map
37   * @since 4.0
38   */
39  public class DualLinkedHashBidiMap<K, V> extends AbstractDualBidiMap<K, V> implements Serializable {
40  
41      /** Ensure serialization compatibility */
42      private static final long serialVersionUID = 721969328361810L;
43  
44      /**
45       * Creates an empty {@code HashBidiMap}.
46       */
47      public DualLinkedHashBidiMap() {
48          super(new LinkedHashMap<>(), new LinkedHashMap<>());
49      }
50  
51      /**
52       * Constructs a {@code LinkedHashBidiMap} and copies the mappings from
53       * specified {@link Map}.
54       *
55       * @param map the map whose mappings are to be placed in this map
56       */
57      public DualLinkedHashBidiMap(final Map<? extends K, ? extends V> map) {
58          super(new LinkedHashMap<>(), new LinkedHashMap<>());
59          putAll(map);
60      }
61  
62      /**
63       * Constructs a {@code LinkedHashBidiMap} that decorates the specified maps.
64       *
65       * @param normalMap      the normal direction map
66       * @param reverseMap     the reverse direction map
67       * @param inverseBidiMap the inverse BidiMap
68       */
69      protected DualLinkedHashBidiMap(final Map<K, V> normalMap, final Map<V, K> reverseMap,
70                                      final BidiMap<V, K> inverseBidiMap) {
71          super(normalMap, reverseMap, inverseBidiMap);
72      }
73  
74      /**
75       * Creates a new instance of this object.
76       *
77       * @param normalMap      the normal direction map
78       * @param reverseMap     the reverse direction map
79       * @param inverseBidiMap the inverse BidiMap
80       * @return new bidi map
81       */
82      @Override
83      protected BidiMap<V, K> createBidiMap(final Map<V, K> normalMap, final Map<K, V> reverseMap,
84              final BidiMap<K, V> inverseBidiMap) {
85          return new DualLinkedHashBidiMap<>(normalMap, reverseMap, inverseBidiMap);
86      }
87  
88      /**
89       * Deserializes an instance from an ObjectInputStream.
90       *
91       * @param in The source ObjectInputStream.
92       * @throws IOException            Any of the usual Input/Output related exceptions.
93       * @throws ClassNotFoundException A class of a serialized object cannot be found.
94       */
95      private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
96          in.defaultReadObject();
97          normalMap = new LinkedHashMap<>();
98          reverseMap = new LinkedHashMap<>();
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     /**
105      * Serializes this object to an ObjectOutputStream.
106      *
107      * @param out the target ObjectOutputStream.
108      * @throws IOException thrown when an I/O errors occur writing to the target stream.
109      */
110     private void writeObject(final ObjectOutputStream out) throws IOException {
111         out.defaultWriteObject();
112         out.writeObject(normalMap);
113     }
114 }