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 */
017package org.apache.commons.collections4;
018
019import java.util.Set;
020
021/**
022 * Defines a map that allows bidirectional lookup between key and values.
023 * <p>
024 * This extended <code>Map</code> represents a mapping where a key may
025 * lookup a value and a value may lookup a key with equal ease.
026 * This interface extends <code>Map</code> and so may be used anywhere a map
027 * is required. The interface provides an inverse map view, enabling
028 * full access to both directions of the <code>BidiMap</code>.
029 * <p>
030 * Implementations should allow a value to be looked up from a key and
031 * a key to be looked up from a value with equal performance.
032 * <p>
033 * This map enforces the restriction that there is a 1:1 relation between
034 * keys and values, meaning that multiple keys cannot map to the same value.
035 * This is required so that "inverting" the map results in a map without
036 * duplicate keys. See the {@link #put} method description for more information.
037 *
038 * @param <K> the type of the keys in the map
039 * @param <V> the type of the values in the map
040 *
041 * @since 3.0
042 */
043public interface BidiMap<K, V> extends IterableMap<K, V> {
044
045    /**
046     * Puts the key-value pair into the map, replacing any previous pair.
047     * <p>
048     * When adding a key-value pair, the value may already exist in the map
049     * against a different key. That mapping is removed, to ensure that the
050     * value only occurs once in the inverse map.
051     * <pre>
052     *  BidiMap map1 = new DualHashBidiMap();
053     *  map.put("A","B");  // contains A mapped to B, as per Map
054     *  map.put("A","C");  // contains A mapped to C, as per Map
055     *
056     *  BidiMap map2 = new DualHashBidiMap();
057     *  map.put("A","B");  // contains A mapped to B, as per Map
058     *  map.put("C","B");  // contains C mapped to B, key A is removed
059     * </pre>
060     *
061     * @param key  the key to store
062     * @param value  the value to store
063     * @return the previous value mapped to this key
064     *
065     * @throws UnsupportedOperationException if the <code>put</code> method is not supported
066     * @throws ClassCastException (optional) if the map limits the type of the
067     *  value and the specified value is inappropriate
068     * @throws IllegalArgumentException (optional) if the map limits the values
069     *  in some way and the value was invalid
070     * @throws NullPointerException (optional) if the map limits the values to
071     *  non-null and null was specified
072     */
073    @Override
074    V put(K key, V value);
075
076    /**
077     * Gets the key that is currently mapped to the specified value.
078     * <p>
079     * If the value is not contained in the map, <code>null</code> is returned.
080     * <p>
081     * Implementations should seek to make this method perform equally as well
082     * as <code>get(Object)</code>.
083     *
084     * @param value  the value to find the key for
085     * @return the mapped key, or <code>null</code> if not found
086     *
087     * @throws ClassCastException (optional) if the map limits the type of the
088     *  value and the specified value is inappropriate
089     * @throws NullPointerException (optional) if the map limits the values to
090     *  non-null and null was specified
091     */
092    K getKey(Object value);
093
094    /**
095     * Removes the key-value pair that is currently mapped to the specified
096     * value (optional operation).
097     * <p>
098     * If the value is not contained in the map, <code>null</code> is returned.
099     * <p>
100     * Implementations should seek to make this method perform equally as well
101     * as <code>remove(Object)</code>.
102     *
103     * @param value  the value to find the key-value pair for
104     * @return the key that was removed, <code>null</code> if nothing removed
105     *
106     * @throws ClassCastException (optional) if the map limits the type of the
107     *  value and the specified value is inappropriate
108     * @throws NullPointerException (optional) if the map limits the values to
109     *  non-null and null was specified
110     * @throws UnsupportedOperationException if this method is not supported
111     *  by the implementation
112     */
113    K removeValue(Object value);
114
115    /**
116     * Gets a view of this map where the keys and values are reversed.
117     * <p>
118     * Changes to one map will be visible in the other and vice versa.
119     * This enables both directions of the map to be accessed as a <code>Map</code>.
120     * <p>
121     * Implementations should seek to avoid creating a new object every time this
122     * method is called. See <code>AbstractMap.values()</code> etc. Calling this
123     * method on the inverse map should return the original.
124     *
125     * @return an inverted bidirectional map
126     */
127    BidiMap<V, K> inverseBidiMap();
128
129    /**
130     * Returns a {@link Set} view of the values contained in this map.
131     * The set is backed by the map, so changes to the map are reflected
132     * in the set, and vice-versa.  If the map is modified while an iteration
133     * over the set is in progress (except through the iterator's own
134     * {@code remove} operation), the results of the iteration are undefined.
135     * The set supports element removal, which removes the corresponding
136     * mapping from the map, via the {@code Iterator.remove},
137     * {@code Collection.remove}, {@code removeAll},
138     * {@code retainAll} and {@code clear} operations.  It does not
139     * support the {@code add} or {@code addAll} operations.
140     *
141     * @return a set view of the values contained in this map
142     */
143    @Override
144    Set<V> values();
145}