001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.collections;
018
019 /**
020 * Defines a map that allows bidirectional lookup between key and values.
021 * <p>
022 * This extended <code>Map</code> represents a mapping where a key may
023 * lookup a value and a value may lookup a key with equal ease.
024 * This interface extends <code>Map</code> and so may be used anywhere a map
025 * is required. The interface provides an inverse map view, enabling
026 * full access to both directions of the <code>BidiMap</code>.
027 * <p>
028 * Implementations should allow a value to be looked up from a key and
029 * a key to be looked up from a value with equal performance.
030 * <p>
031 * This map enforces the restriction that there is a 1:1 relation between
032 * keys and values, meaning that multiple keys cannot map to the same value.
033 * This is required so that "inverting" the map results in a map without
034 * duplicate keys. See the {@link #put} method description for more information.
035 *
036 * @since Commons Collections 3.0
037 * @version $Revision: 646777 $ $Date: 2008-04-10 13:33:15 +0100 (Thu, 10 Apr 2008) $
038 *
039 * @author Stephen Colebourne
040 */
041 public interface BidiMap extends IterableMap {
042
043 /**
044 * Obtains a <code>MapIterator</code> over the map.
045 * <p>
046 * A map iterator is an efficient way of iterating over maps.
047 * It does not require that the map is stored using Map Entry objects
048 * which can increase performance.
049 * <pre>
050 * BidiMap map = new DualHashBidiMap();
051 * MapIterator it = map.mapIterator();
052 * while (it.hasNext()) {
053 * Object key = it.next();
054 * Object value = it.getValue();
055 * it.setValue("newValue");
056 * }
057 * </pre>
058 *
059 * @return a map iterator
060 */
061 MapIterator mapIterator();
062
063 /**
064 * Puts the key-value pair into the map, replacing any previous pair.
065 * <p>
066 * When adding a key-value pair, the value may already exist in the map
067 * against a different key. That mapping is removed, to ensure that the
068 * value only occurs once in the inverse map.
069 * <pre>
070 * BidiMap map1 = new DualHashBidiMap();
071 * map.put("A","B"); // contains A mapped to B, as per Map
072 * map.put("A","C"); // contains A mapped to C, as per Map
073 *
074 * BidiMap map2 = new DualHashBidiMap();
075 * map.put("A","B"); // contains A mapped to B, as per Map
076 * map.put("C","B"); // contains C mapped to B, key A is removed
077 * </pre>
078 *
079 * @param key the key to store
080 * @param value the value to store
081 * @return the previous value mapped to this key
082 *
083 * @throws UnsupportedOperationException if the <code>put</code> method is not supported
084 * @throws ClassCastException (optional) if the map limits the type of the
085 * value and the specified value is inappropriate
086 * @throws IllegalArgumentException (optional) if the map limits the values
087 * in some way and the value was invalid
088 * @throws NullPointerException (optional) if the map limits the values to
089 * non-null and null was specified
090 */
091 Object put(Object key, Object value);
092
093 /**
094 * Gets the key that is currently mapped to the specified value.
095 * <p>
096 * If the value is not contained in the map, <code>null</code> is returned.
097 * <p>
098 * Implementations should seek to make this method perform equally as well
099 * as <code>get(Object)</code>.
100 *
101 * @param value the value to find the key for
102 * @return the mapped key, or <code>null</code> if not found
103 *
104 * @throws ClassCastException (optional) if the map limits the type of the
105 * value and the specified value is inappropriate
106 * @throws NullPointerException (optional) if the map limits the values to
107 * non-null and null was specified
108 */
109 Object getKey(Object value);
110
111 /**
112 * Removes the key-value pair that is currently mapped to the specified
113 * value (optional operation).
114 * <p>
115 * If the value is not contained in the map, <code>null</code> is returned.
116 * <p>
117 * Implementations should seek to make this method perform equally as well
118 * as <code>remove(Object)</code>.
119 *
120 * @param value the value to find the key-value pair for
121 * @return the key that was removed, <code>null</code> if nothing removed
122 *
123 * @throws ClassCastException (optional) if the map limits the type of the
124 * value and the specified value is inappropriate
125 * @throws NullPointerException (optional) if the map limits the values to
126 * non-null and null was specified
127 * @throws UnsupportedOperationException if this method is not supported
128 * by the implementation
129 */
130 Object removeValue(Object value);
131
132 /**
133 * Gets a view of this map where the keys and values are reversed.
134 * <p>
135 * Changes to one map will be visible in the other and vice versa.
136 * This enables both directions of the map to be accessed as a <code>Map</code>.
137 * <p>
138 * Implementations should seek to avoid creating a new object every time this
139 * method is called. See <code>AbstractMap.values()</code> etc. Calling this
140 * method on the inverse map should return the original.
141 *
142 * @return an inverted bidirectional map
143 */
144 BidiMap inverseBidiMap();
145
146 }