// no null keys or null values sclass BijectiveMap extends CompactAbstractMap { new Map forward; new Map backward; *() {} *(bool ordered) { if (ordered) { forward = new LinkedHashMap; backward = new LinkedHashMap; } } @Override public B put(A a, B b) { assertNotNull(a); assertNotNull(b); A oldKey = backward.get(b); if (eq(oldKey, a)) ret b; // nothing to do // remove old mapping of b if (oldKey != null) forward.remove(oldKey); // remove old mapping of a B oldValue = forward.get(a); if (oldValue != null) backward.remove(b); // add/overwrite new mapping backward.put(b, a); ret forward.put(a, b); } @Override public B remove(O a) { B b = forward.get(a); if (b != null) { forward.remove(a); backward.remove(b); } ret b; } @Override public B get(O a) { ret forward.get(a); } A inverseGet(B b) { ret backward.get(b); } public Set keySet() { ret immutableSet(forward.keySet()); } public Set valueSet() { ret immutableSet(backward.keySet()); } public Set> entrySet() { ret immutableSet(forward.entrySet()); } public int size() { ret forward.size(); } Map forwardMap() { ret immutableMap(forward); } Map backwardMap() { ret immutableMap(backward); } }