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 }