Last active
August 29, 2015 14:02
-
-
Save DarkSeraphim/dce060e6686c22401f8f to your computer and use it in GitHub Desktop.
Map with multiple keys to the same value, strict implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.darkseraphim.dungeons.util; | |
import org.apache.commons.lang.Validate; | |
import java.util.HashMap; | |
import java.util.Map; | |
/** | |
* @Author DarkSeraphim | |
*/ | |
public class AmirMap<K, L, V> | |
{ | |
Map<K, L> kl = new HashMap<K, L>(); | |
Map<L, K> lk = new HashMap<L, K>(); | |
Map<K, V> kv = new HashMap<K, V>(); | |
Map<L, V> lv = new HashMap<L, V>(); | |
private final Class<K> k; | |
private final Class<L> l; | |
private AmirMap(Class<K> k, Class<L> l) | |
{ | |
this.k = k; | |
this.l = l; | |
} | |
public V get(Object key) | |
{ | |
Validate.notNull(key, "null keys not supported"); | |
if(key.getClass().isAssignableFrom(this.k)) | |
return this.getK((K) key); | |
else if(key.getClass().isAssignableFrom(this.l)) | |
return this.getL((L) key); | |
throw new ClassCastException(String.format("Cannot cast %s to %s nor %s", key.getClass().toString(), this.k.toString(), this.l.toString())); | |
} | |
private V getK(K key) | |
{ | |
return this.kv.get(key); | |
} | |
private V getL(L key) | |
{ | |
return this.lv.get(key); | |
} | |
public V put(K key, L key2, V val) | |
{ | |
V a = this.kv.put(key, val); | |
V b = this.lv.put(key2, val); | |
if (a != b) | |
throw new IllegalStateException("Contract violated"); | |
return a; | |
} | |
public V remove(Object key) | |
{ | |
Validate.notNull(key, "null keys not supported"); | |
if(key.getClass().isAssignableFrom(this.k)) | |
return this.removeK((K) key); | |
else if(key.getClass().isAssignableFrom(this.l)) | |
return this.removeL((L) key); | |
throw new ClassCastException(String.format("Cannot cast %s to %s nor %s", key.getClass().toString(), this.k.toString(), this.l.toString())); | |
} | |
private V removeK(K key) | |
{ | |
L partner = this.kl.get(key); | |
if (partner == null) | |
throw new IllegalStateException("Contract violated"); | |
V a = this.kv.remove(key); | |
V b = this.lv.remove(partner); | |
if (a != b) | |
throw new IllegalStateException("Contract violated"); | |
return a; | |
} | |
private V removeL(L key) | |
{ | |
K partner = this.lk.get(key); | |
if (partner == null) | |
throw new IllegalStateException("Contract violated"); | |
V a = this.lv.remove(key); | |
V b = this.kv.remove(partner); | |
if (a != b) | |
throw new IllegalStateException("Contract violated"); | |
return a; | |
} | |
public boolean containsKey(Object key) | |
{ | |
Validate.notNull(key, "null keys not supported"); | |
if(key.getClass().isAssignableFrom(this.k)) | |
return this.containsKeyK((K) key); | |
else if(key.getClass().isAssignableFrom(this.l)) | |
return this.containsKeyL((L) key); | |
throw new ClassCastException(String.format("Cannot cast %s to %s nor %s", key.getClass().toString(), this.k.toString(), this.l.toString())); | |
} | |
public boolean containsKeyK(K key) | |
{ | |
L part = this.kl.get(key); | |
if (part == null) | |
throw new IllegalStateException("Contract violated"); | |
boolean ret = this.kv.containsKey(key); | |
if (this.lv.containsKey(part) != ret) | |
throw new IllegalStateException("Contract violated"); | |
return ret; | |
} | |
public boolean containsKeyL(L key) | |
{ | |
K part = this.lk.get(key); | |
if (part == null) | |
throw new IllegalStateException("Contract violated"); | |
boolean ret = this.lv.containsKey(key); | |
if (this.kv.containsKey(part) != ret) | |
throw new IllegalStateException("Contract violated"); | |
return ret; | |
} | |
public static <K, L, V> AmirMap<K, L, V> create(Class<K> k, Class<L> l, Class<V> v) | |
{ | |
if (k == l) | |
throw new IllegalArgumentException("K cannot be the same as L"); | |
return new AmirMap<K, L, V>(k, l); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment