1 package org.simantics.interop.utils;
\r
3 import java.util.ArrayList;
\r
4 import java.util.Collection;
\r
5 import java.util.Collections;
\r
6 import java.util.LinkedHashMap;
\r
7 import java.util.Map;
\r
8 import java.util.Set;
\r
9 import java.util.Map.Entry;
\r
11 import org.simantics.utils.datastructures.BijectionMap;
\r
13 public class LinkedBijectionMap<L, R> {
\r
14 /** The keys of tableLeft are left-side-values and
\r
15 * values are right-side-values */
\r
16 private final Map<L, R> tableLeft = new LinkedHashMap<L, R>();
\r
17 /** The keys of tableRight are right-side-values and
\r
18 * values on it are left-side-values */
\r
19 private final Map<R, L> tableRight = new LinkedHashMap<R, L>();
\r
21 /** The keys of tableLeft are left-side-values and
\r
22 * values are right-side-values */
\r
23 private final Map<L, R> imTableLeft = Collections.unmodifiableMap(tableLeft);
\r
24 /** The keys of tableRight are right-side-values and
\r
25 * values on it are left-side-values */
\r
26 private final Map<R, L> imTableRight = Collections.unmodifiableMap(tableRight);
\r
28 private final Set<L> imLeftSet = Collections.unmodifiableSet(tableLeft.keySet());
\r
29 private final Set<R> imRightSet = Collections.unmodifiableSet(tableRight.keySet());
\r
31 public LinkedBijectionMap() {
\r
35 public LinkedBijectionMap(LinkedBijectionMap<L, R> copyFrom) {
\r
36 this.tableLeft.putAll(copyFrom.tableLeft);
\r
37 this.tableRight.putAll(copyFrom.tableRight);
\r
40 public void addAll(BijectionMap<L, R> map)
\r
42 for (Entry<L, R> e : map.getEntries())
\r
43 map(e.getKey(), e.getValue());
\r
46 public boolean retainAllLeft(Collection<L> values)
\r
48 boolean result = false;
\r
49 Collection<L> remove = new ArrayList<L>(size());
\r
50 for (L lValue : imLeftSet) {
\r
51 if (!values.contains(lValue)) {
\r
56 if (!remove.isEmpty()) {
\r
57 for (L lValue : remove)
\r
58 removeWithLeft(lValue);
\r
63 public boolean retainAllRight(Collection<R> values)
\r
65 boolean result = false;
\r
66 Collection<R> remove = new ArrayList<R>(size());
\r
67 for (R rValue : imRightSet) {
\r
68 if (!values.contains(rValue)) {
\r
73 if (!remove.isEmpty()) {
\r
74 for (R rValue : remove)
\r
75 removeWithRight(rValue);
\r
80 public Set<Entry<L, R>> getEntries()
\r
82 return tableLeft.entrySet();
\r
85 public boolean containsLeft(L leftValue)
\r
87 return tableLeft.containsKey(leftValue);
\r
90 public boolean containsRight(R rightValue)
\r
92 return tableRight.containsKey(rightValue);
\r
95 public boolean contains(L leftValue, R rightValue)
\r
97 if (leftValue==null || rightValue==null) return false;
\r
98 return rightValue.equals(tableLeft.get(leftValue));
\r
101 public void map(L leftValue, R rightValue)
\r
103 if (leftValue == null || rightValue == null)
\r
104 throw new NullPointerException();
\r
105 // Remove possible old mapping
\r
106 R oldRight = tableLeft.remove(leftValue);
\r
107 if (oldRight != null) {
\r
108 tableRight.remove(oldRight);
\r
110 L oldLeft = tableRight.remove(rightValue);
\r
111 if (oldLeft != null) {
\r
112 tableLeft.remove(oldLeft);
\r
116 tableLeft.put(leftValue, rightValue);
\r
117 tableRight.put(rightValue, leftValue);
\r
120 public boolean isEmpty() {
\r
121 return tableLeft.isEmpty();
\r
126 return tableLeft.size();
\r
129 public L getLeft(R rightValue) {
\r
130 return tableRight.get(rightValue);
\r
133 public R getRight(L leftValue) {
\r
134 return tableLeft.get(leftValue);
\r
137 public R removeWithLeft(L leftValue) {
\r
138 R rightValue = tableLeft.remove(leftValue);
\r
139 if (rightValue!=null)
\r
140 tableRight.remove(rightValue);
\r
144 public L removeWithRight(R rightValue) {
\r
145 L leftValue = tableRight.remove(rightValue);
\r
146 if (leftValue!=null)
\r
147 tableLeft.remove(leftValue);
\r
152 * Get set of left values
\r
154 * @return read-only set
\r
156 public Set<L> getLeftSet() {
\r
161 * Get set of right values
\r
163 * @return read-only set
\r
165 public Set<R> getRightSet() {
\r
170 * Get left-to-right map
\r
172 * @return read only map
\r
174 public Map<L, R> getLeftToRightMap() {
\r
175 return imTableLeft;
\r
179 * Get right-to-left map
\r
181 * @return read only map
\r
183 public Map<R, L> getRightToLeftMap() {
\r
184 return imTableRight;
\r
187 public void clear() {
\r
189 tableRight.clear();
\r
193 public String toString() {
\r
195 StringBuilder sb = new StringBuilder();
\r
197 for (Entry<L, R> e : tableLeft.entrySet())
\r
199 if (count++>0) sb.append(", ");
\r
200 sb.append(e.getKey().toString());
\r
202 sb.append(e.getValue().toString());
\r
205 return sb.toString();
\r
209 public LinkedBijectionMap<L, R> clone() {
\r
210 return new LinkedBijectionMap<L, R>(this);
\r