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 }