Author: michiel
Date: 2009-05-18 19:04:25 +0200 (Mon, 18 May 2009)
New Revision: 35272

Added:
   mmbase/trunk/src/org/mmbase/util/BijectiveMap.java
Log:
A utitily structure which can come in handy

Added: mmbase/trunk/src/org/mmbase/util/BijectiveMap.java
===================================================================
--- mmbase/trunk/src/org/mmbase/util/BijectiveMap.java                          
(rev 0)
+++ mmbase/trunk/src/org/mmbase/util/BijectiveMap.java  2009-05-18 17:04:25 UTC 
(rev 35272)
@@ -0,0 +1,84 @@
+package org.mmbase.util;
+
+import java.util.*;
+
+/**
+ * A map representing a 1-1 bijective relation between 2 sets of values.
+ *
+ * @author Michiel Meeuwissen
+ * @since MMBase-1.9.1
+ * @version $Id$
+ */
+
+
+public class BijectiveMap<K, V> extends AbstractMap<K, V> {
+
+    private final Map<K, V> backing;
+    private final Map<V, K> inverse;
+
+    public BijectiveMap() {
+        backing = new HashMap<K, V>();
+        inverse = new HashMap<V, K>();
+    }
+    private BijectiveMap(Map<K, V> backing, Map<V, K> inverse) {
+        this.backing = backing;
+        this.inverse = inverse;
+    }
+
+    @Override
+    public Set<Map.Entry<K, V>> entrySet() {
+        return new AbstractSet<Map.Entry<K, V>>() {
+            @Override
+            public int size() {
+                return backing.size();
+            }
+            @Override
+            public Iterator<Map.Entry<K, V>> iterator() {
+                return new Iterator<Map.Entry<K, V>>() {
+                    private final Iterator<Map.Entry<K, V>> i = 
backing.entrySet().iterator();
+                    private Map.Entry<K, V> entry;
+                    public boolean hasNext() {
+                        return i.hasNext();
+                    }
+                    public Map.Entry<K, V> next() {
+                        entry = i.next();
+                        return entry;
+                    }
+                    public void remove() {
+                        i.remove();
+                        inverse.remove(entry.getValue());
+
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public V put(K key, V value) {
+        if (backing.containsKey(key)) {
+            V prevValue = backing.get(key);
+            if (! prevValue.equals(value)) {
+                if (inverse.containsKey(value)) throw new 
IllegalArgumentException();
+                inverse.remove(prevValue);
+                inverse.put(value, key);
+                backing.put(key, value);
+            }
+            return prevValue;
+        } else {
+            if (inverse.containsKey(value)) {
+                throw new IllegalArgumentException("Cannot put " + key + "->" 
+ value + " Because the value already exists " + inverse);
+            }
+            backing.put(key, value);
+            inverse.put(value, key);
+            return null;
+        }
+    }
+
+    public K inverseGet(V value) {
+        return inverse.get(value);
+    }
+    public Map<V, K> getInverse() {
+        return new BijectiveMap<V, K>(inverse, backing);
+    }
+}


Property changes on: mmbase/trunk/src/org/mmbase/util/BijectiveMap.java
___________________________________________________________________
Name: svn:keywords
   + Id

_______________________________________________
Cvs mailing list
[email protected]
http://lists.mmbase.org/mailman/listinfo/cvs

Reply via email to