001 /*--------------------------------------------------------------------------+
002 $Id: BidirectionalMap.java 26283 2010-02-18 11:18:57Z juergens $
003 | |
004 | Copyright 2005-2010 Technische Universitaet Muenchen |
005 | |
006 | Licensed under the Apache License, Version 2.0 (the "License"); |
007 | you may not use this file except in compliance with the License. |
008 | You may obtain a copy of the License at |
009 | |
010 | http://www.apache.org/licenses/LICENSE-2.0 |
011 | |
012 | Unless required by applicable law or agreed to in writing, software |
013 | distributed under the License is distributed on an "AS IS" BASIS, |
014 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
015 | See the License for the specific language governing permissions and |
016 | limitations under the License. |
017 +--------------------------------------------------------------------------*/
018 package edu.tum.cs.commons.collections;
019
020 import java.util.HashMap;
021 import java.util.Map;
022 import java.util.Map.Entry;
023
024 import edu.tum.cs.commons.assertion.CCSMPre;
025
026 /**
027 * A collection which implements a bidirectional mapping.
028 *
029 * @author hummelb
030 * @author $Author: juergens $
031 * @version $Rev: 26283 $
032 * @levd.rating GREEN Hash: F1003ED1FCC22EA4403DCC0EAC9625F2
033 */
034 public class BidirectionalMap<S, T> {
035
036 /** Mapping from s to t. */
037 private final Map<S, T> stMap;
038
039 /** Mapping from t to s. */
040 private final Map<T, S> tsMap;
041
042 /** Creates new bidirectional map based on hash maps. */
043 public BidirectionalMap() {
044 stMap = new HashMap<S, T>();
045 tsMap = new HashMap<T, S>();
046 }
047
048 /** Creates new bidirectional map based given maps. */
049 @SuppressWarnings("null")
050 public BidirectionalMap(Map<S, T> stMap, Map<T, S> tsMap) {
051 CCSMPre.isTrue(stMap != null && tsMap != null, "Maps may not be null!");
052 CCSMPre.isTrue(stMap != tsMap, "Maps may not be equal!");
053 CCSMPre.isTrue(stMap.isEmpty() && tsMap.isEmpty(),
054 "Maps may not be used (filled)!");
055
056 this.stMap = stMap;
057 this.tsMap = tsMap;
058 }
059
060 /** Get first element. */
061 public S getFirst(T t) {
062 return tsMap.get(t);
063 }
064
065 /** Get second element. */
066 public T getSecond(S s) {
067 return stMap.get(s);
068 }
069
070 /** Returns whether this map is empty. */
071 public boolean isEmpty() {
072 return stMap.isEmpty();
073 }
074
075 /** Returns the size. */
076 public int size() {
077 return stMap.size();
078 }
079
080 /** Clears the map. */
081 public void clear() {
082 stMap.clear();
083 tsMap.clear();
084 }
085
086 /**
087 * Returns whether the given element is in the first set (the domain of the
088 * bijection).
089 */
090 public boolean containsFirst(S s) {
091 return stMap.containsKey(s);
092 }
093
094 /**
095 * Returns whether the given element is in the second set (the range of the
096 * bijection).
097 */
098 public boolean containsSecond(T t) {
099 return tsMap.containsKey(t);
100 }
101
102 /** Returns the first set (the domain). */
103 public UnmodifiableSet<S> getFirstSet() {
104 return CollectionUtils.asUnmodifiable(stMap.keySet());
105 }
106
107 /** Returns the second set (the range). */
108 public UnmodifiableSet<T> getSecondSet() {
109 return CollectionUtils.asUnmodifiable(tsMap.keySet());
110 }
111
112 /** Returns the entries. */
113 public UnmodifiableSet<Entry<S, T>> getEntrySet() {
114 return CollectionUtils.asUnmodifiable(stMap.entrySet());
115 }
116
117 /** Returns the inverted entries. */
118 public UnmodifiableSet<Entry<T, S>> getInvertedEntrySet() {
119 return CollectionUtils.asUnmodifiable(tsMap.entrySet());
120 }
121
122 /**
123 * Inserts the given pair into the bijection. Any mapping associated with
124 * those values is removed before. This map does not support null values.
125 */
126 public void put(S s, T t) {
127 CCSMPre.isTrue(s != null && t != null, "null values not supported.");
128
129 removeFirst(s);
130 removeSecond(t);
131
132 stMap.put(s, t);
133 tsMap.put(t, s);
134 }
135
136 /** Removes the first object */
137 public void removeFirst(S s) {
138 T t = stMap.get(s);
139 if (t != null) {
140 stMap.remove(s);
141 tsMap.remove(t);
142 }
143 }
144
145 /** Removes the second object */
146 public void removeSecond(T t) {
147 S s = tsMap.get(t);
148 if (s != null) {
149 stMap.remove(s);
150 tsMap.remove(t);
151 }
152 }
153
154 }