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;
18
19 import java.util.Set;
20
21 /**
22 * Defines a map that allows bidirectional lookup between key and values.
23 * <p>
24 * This extended {@code Map} represents a mapping where a key may
25 * lookup a value and a value may lookup a key with equal ease.
26 * This interface extends {@code Map} and so may be used anywhere a map
27 * is required. The interface provides an inverse map view, enabling
28 * full access to both directions of the {@code BidiMap}.
29 * </p>
30 * <p>
31 * Implementations should allow a value to be looked up from a key and
32 * a key to be looked up from a value with equal performance.
33 * </p>
34 * <p>
35 * This map enforces the restriction that there is a 1:1 relation between
36 * keys and values, meaning that multiple keys cannot map to the same value.
37 * This is required so that "inverting" the map results in a map without
38 * duplicate keys. See the {@link #put} method description for more information.
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 interface BidiMap<K, V> extends IterableMap<K, V> {
46
47 /**
48 * Gets the key that is currently mapped to the specified value.
49 * <p>
50 * If the value is not contained in the map, {@code null} is returned.
51 * </p>
52 * <p>
53 * Implementations should seek to make this method perform equally as well
54 * as {@code get(Object)}.
55 * </p>
56 *
57 * @param value the value to find the key for
58 * @return the mapped key, or {@code null} if not found
59 * @throws ClassCastException (optional) if the map limits the type of the
60 * value and the specified value is inappropriate
61 * @throws NullPointerException (optional) if the map limits the values to
62 * non-null and null was specified
63 */
64 K getKey(Object value);
65
66 /**
67 * Gets a view of this map where the keys and values are reversed.
68 * <p>
69 * Changes to one map will be visible in the other and vice versa.
70 * This enables both directions of the map to be accessed as a {@code Map}.
71 * </p>
72 * <p>
73 * Implementations should seek to avoid creating a new object every time this
74 * method is called. See {@code AbstractMap.values()} etc. Calling this
75 * method on the inverse map should return the original.
76 * </p>
77 *
78 * @return an inverted bidirectional map
79 */
80 BidiMap<V, K> inverseBidiMap();
81
82 /**
83 * Puts the key-value pair into the map, replacing any previous pair.
84 * <p>
85 * When adding a key-value pair, the value may already exist in the map
86 * against a different key. That mapping is removed, to ensure that the
87 * value only occurs once in the inverse map.
88 * </p>
89 * <pre>
90 * BidiMap map1 = new DualHashBidiMap();
91 * map.put("A","B"); // contains A mapped to B, as per Map
92 * map.put("A","C"); // contains A mapped to C, as per Map
93 *
94 * BidiMap map2 = new DualHashBidiMap();
95 * map.put("A","B"); // contains A mapped to B, as per Map
96 * map.put("C","B"); // contains C mapped to B, key A is removed
97 * </pre>
98 *
99 * @param key the key to store
100 * @param value the value to store
101 * @return the previous value mapped to this key
102 * @throws UnsupportedOperationException if the {@code put} method is not supported
103 * @throws ClassCastException (optional) if the map limits the type of the
104 * value and the specified value is inappropriate
105 * @throws IllegalArgumentException (optional) if the map limits the values
106 * in some way and the value was invalid
107 * @throws NullPointerException (optional) if the map limits the values to
108 * non-null and null was specified
109 */
110 @Override
111 V put(K key, V value);
112
113 /**
114 * Removes the key-value pair that is currently mapped to the specified
115 * value (optional operation).
116 * <p>
117 * If the value is not contained in the map, {@code null} is returned.
118 * </p>
119 * <p>
120 * Implementations should seek to make this method perform equally as well
121 * as {@code remove(Object)}.
122 * </p>
123 *
124 * @param value the value to find the key-value pair for
125 * @return the key that was removed, {@code null} if nothing removed
126 * @throws ClassCastException (optional) if the map limits the type of the
127 * value and the specified value is inappropriate
128 * @throws NullPointerException (optional) if the map limits the values to
129 * non-null and null was specified
130 * @throws UnsupportedOperationException if this method is not supported
131 * by the implementation
132 */
133 K removeValue(Object value);
134
135 /**
136 * Returns a {@link Set} view of the values contained in this map.
137 * The set is backed by the map, so changes to the map are reflected
138 * in the set, and vice-versa. If the map is modified while an iteration
139 * over the set is in progress (except through the iterator's own
140 * {@code remove} operation), the results of the iteration are undefined.
141 * The set supports element removal, which removes the corresponding
142 * mapping from the map, via the {@code Iterator.remove},
143 * {@code Collection.remove}, {@code removeAll},
144 * {@code retainAll} and {@code clear} operations. It does not
145 * support the {@code add} or {@code addAll} operations.
146 *
147 * @return a set view of the values contained in this map
148 */
149 @Override
150 Set<V> values();
151 }