changeset 59:6e08ff123ae6

check in complete source of cl.maps.
author casties
date Wed, 14 Dec 2016 15:49:40 +0100
parents 153a0232270b
children cc7a6fe4ee7a
files src/main/java/cl/maps/duplex/DuplexKey.java src/main/java/cl/maps/duplex/IDuplexMap.java src/main/java/cl/maps/penta/IPentaMap.java src/main/java/cl/maps/penta/PentaKey.java src/main/java/cl/maps/penta/PentaMap.java src/main/java/cl/maps/quad/IQuadMap.java src/main/java/cl/maps/quad/QuadKey.java src/main/java/cl/maps/quad/QuadMap.java src/main/java/cl/maps/triple/ITripleMap.java src/main/java/cl/maps/triple/TripleKey.java src/main/java/cl/maps/triple/TripleMap.java
diffstat 11 files changed, 1262 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/cl/maps/duplex/DuplexKey.java	Wed Dec 14 15:49:40 2016 +0100
@@ -0,0 +1,81 @@
+package cl.maps.duplex;
+
+
+public class DuplexKey<A, B> {
+	
+	private A aKey;
+	private B ownKey;
+	
+	public DuplexKey(A aKey, B ownKey){
+		this.aKey = aKey;
+		this.ownKey = ownKey;
+	}
+	
+	public boolean equalsAKey(A key){
+		if(aKey != null && key != null){
+			return aKey.equals(key);
+		}else if(aKey == null && key == null){
+			return true;
+		}
+		return false;
+	}
+	
+	public boolean equalsOwnKey(B key){
+		if(ownKey != null && key != null){
+			return ownKey.equals(key);
+		}else if(ownKey == null && key == null){
+			return true;
+		}
+		return false;
+	}
+	
+	public A getAKey() {
+		return aKey;
+	}
+
+	public void setAKey(A aKey) {
+		this.aKey = aKey;
+	}
+
+	public B getOwnKey() {
+		return ownKey;
+	}
+
+	public void setOwnKey(B ownKey) {
+		this.ownKey = ownKey;
+	}
+	
+	@Override
+	public boolean equals(Object o){
+		if(o instanceof DuplexKey){
+			try {
+				DuplexKey<A, B> other = (DuplexKey<A, B>)o;
+				
+				if(this.equalsOwnKey(other.getOwnKey()) &&
+						this.equalsAKey(other.getAKey())){
+					return true;
+				}	
+			} catch (Exception e) {}
+			
+		}
+		return false;
+	}
+	
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((aKey == null) ? 0 : aKey.hashCode());
+		result = prime * result + ((ownKey == null) ? 0 : ownKey.hashCode());
+		
+		return result;
+	}
+
+	@Override
+	public String toString() {
+		if (aKey == null || ownKey == null) {
+			return super.toString();
+		}
+		return "DuplexKey [" + aKey.toString() + ", " + ownKey.toString() + "]";
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/cl/maps/duplex/IDuplexMap.java	Wed Dec 14 15:49:40 2016 +0100
@@ -0,0 +1,52 @@
+package cl.maps.duplex;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import cl.maps.quad.QuadKey;
+
+public interface IDuplexMap<V, A, B> {
+
+	int size();
+	
+	boolean isEmpty();
+
+	boolean containsKey(DuplexKey<A, B> key);
+
+	boolean containsValue(Object value);
+	
+	V get(DuplexKey<A, B> key);
+	
+	V put(DuplexKey<A, B> key, V value);
+
+	V remove(DuplexKey<A, B> key);
+
+	//void putAll(Map<? extends K, ? extends V> m);
+
+	void clear();
+
+	Set<DuplexKey<A, B>> keySet();
+
+	Collection<V> values();
+
+	Set<Map.Entry<DuplexKey<A, B>, V>> entrySet();
+
+	boolean equals(Object o);
+
+	/**
+	  * Returns the hash code value for this map.  The hash code of a map is
+	  * defined to be the sum of the hash codes of each entry in the map's
+	  * <tt>entrySet()</tt> view.  This ensures that <tt>m1.equals(m2)</tt>
+	  * implies that <tt>m1.hashCode()==m2.hashCode()</tt> for any two maps
+	  * <tt>m1</tt> and <tt>m2</tt>, as required by the general contract of
+	  * {@link Object#hashCode}.
+	  *
+	  * @return the hash code value for this map
+	  * @see Map.Entry#hashCode()
+	  * @see Object#equals(Object)
+	  * @see #equals(Object)
+	  */
+	int hashCode();
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/cl/maps/penta/IPentaMap.java	Wed Dec 14 15:49:40 2016 +0100
@@ -0,0 +1,52 @@
+package cl.maps.penta;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+
+public interface IPentaMap<V, A, B, C, D, E> {
+
+	int size();
+	
+	boolean isEmpty();
+
+	boolean containsKey(PentaKey<A, B, C, D, E> key);
+
+	boolean containsValue(Object value);
+	
+	V get(PentaKey<A, B, C, D, E> key);
+	
+	V put(PentaKey<A, B, C, D, E> key, V value);
+
+	V remove(PentaKey<A, B, C, D, E> key);
+
+	//void putAll(Map<? extends K, ? extends V> m);
+
+	void clear();
+
+	Set<PentaKey<A, B, C, D, E>> keySet();
+
+	Collection<V> values();
+
+	Set<Map.Entry<PentaKey<A, B, C, D, E>, V>> entrySet();
+
+	boolean equals(Object o);
+
+	/**
+	  * Returns the hash code value for this map.  The hash code of a map is
+	  * defined to be the sum of the hash codes of each entry in the map's
+	  * <tt>entrySet()</tt> view.  This ensures that <tt>m1.equals(m2)</tt>
+	  * implies that <tt>m1.hashCode()==m2.hashCode()</tt> for any two maps
+	  * <tt>m1</tt> and <tt>m2</tt>, as required by the general contract of
+	  * {@link Object#hashCode}.
+	  *
+	  * @return the hash code value for this map
+	  * @see Map.Entry#hashCode()
+	  * @see Object#equals(Object)
+	  * @see #equals(Object)
+	  */
+	int hashCode();
+
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/cl/maps/penta/PentaKey.java	Wed Dec 14 15:49:40 2016 +0100
@@ -0,0 +1,146 @@
+package cl.maps.penta;
+
+
+public class PentaKey <A, B, C, D, E> {
+	private A aKey;
+	private B bKey;
+	private C cKey;
+	private D dKey;
+	private E ownKey;
+	
+	public PentaKey(A aKey, B bKey, C cKey, D dKey, E ownKey){
+		this.aKey = aKey;
+		this.bKey = bKey;
+		this.cKey = cKey;
+		this.dKey = dKey;
+		this.ownKey = ownKey;
+	}
+	
+	public boolean equalsAKey(A key){
+		if(aKey != null && key != null){
+			return aKey.equals(key);
+		}else if(aKey == null && key == null){
+			return true;
+		}
+		return false;
+	}
+	
+	public boolean equalsBKey(B key){
+		if(bKey != null && key != null){
+			return bKey.equals(key);
+		}else if(bKey == null && key == null){
+			return true;
+		}
+		return false;
+	}
+	
+	public boolean equalsCKey(C key){
+		if(cKey != null && key != null){
+			return cKey.equals(key);
+		}else if(cKey == null && key == null){
+			return true;
+		}
+		return false;
+	}
+	
+	public boolean equalsDKey(D key){
+		if(dKey != null && key != null){
+			return dKey.equals(key);
+		}else if(dKey == null && key == null){
+			return true;
+		}
+		return false;
+	}
+	
+	public boolean equalsOwnKey(E key){
+		if(ownKey != null && key != null){
+			return ownKey.equals(key);
+		}else if(ownKey == null && key == null){
+			return true;
+		}
+		return false;
+	}
+	
+	public A getAKey() {
+		return aKey;
+	}
+
+	public void setAKey(A aKey) {
+		this.aKey = aKey;
+	}
+
+	public B getBKey() {
+		return bKey;
+	}
+
+	public void setBKey(B bKey) {
+		this.bKey = bKey;
+	}
+
+	public D getDKey() {
+		return dKey;
+	}
+
+	public void setDKey(D dKey) {
+		this.dKey = dKey;
+	}
+	
+	public C getCKey() {
+		return cKey;
+	}
+
+	public void setCKey(C cKey) {
+		this.cKey = cKey;
+	}
+
+	public E getOwnKey() {
+		return ownKey;
+	}
+
+	public void setOwnKey(E ownKey) {
+		this.ownKey = ownKey;
+	}
+
+	@Override
+	public boolean equals(Object o){
+		if(o instanceof PentaKey){
+			try {
+				PentaKey<A, B, C, D, E> other = (PentaKey<A, B, C, D, E>)o;
+				
+				if(this.equalsDKey(other.getDKey()) &&
+						this.equalsAKey(other.getAKey()) &&
+						this.equalsBKey(other.getBKey()) &&
+						this.equalsCKey(other.getCKey())){
+					return true;
+				}	
+			} catch (Exception e) {}			
+		}
+		return false;
+	}
+	
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((aKey == null) ? 0 : aKey.hashCode());
+		result = prime * result + ((bKey == null) ? 0 : bKey.hashCode());
+		result = prime * result + ((cKey == null) ? 0 : cKey.hashCode());
+		result = prime * result + ((dKey == null) ? 0 : dKey.hashCode());
+		result = prime * result + ((ownKey == null) ? 0 : ownKey.hashCode());
+		
+		return result;
+	}
+
+	@Override
+	public String toString() {
+		if (aKey == null || bKey == null || cKey == null || dKey == null || ownKey == null) {
+			return super.toString();
+		}
+		return "PentaKey [" + 
+			aKey.toString() + ", " + 
+			bKey.toString() + ", " +
+			cKey.toString() + ", " +
+			dKey.toString() + ", " +
+			ownKey.toString() + "]";
+	}	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/cl/maps/penta/PentaMap.java	Wed Dec 14 15:49:40 2016 +0100
@@ -0,0 +1,224 @@
+package cl.maps.penta;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class PentaMap<V, A, B, C, D, E> implements IPentaMap<V, A, B, C, D, E>{
+	
+	private Map<PentaKey<A, B, C, D, E>, V> map;
+	private Map<A, List<PentaKey<A, B, C, D, E>>> mapAKey;
+	private Map<B, List<PentaKey<A, B, C, D, E>>> mapBKey;
+	private Map<C, List<PentaKey<A, B, C, D, E>>> mapCKey;
+	private Map<D, List<PentaKey<A, B, C, D, E>>> mapDKey;
+	private Map<E, PentaKey<A, B, C, D, E>> mapOwnKey;
+	
+	public PentaMap(){
+		this.map  = new HashMap<PentaKey<A, B, C, D, E>, V>();
+		this.mapAKey = new HashMap<A, List<PentaKey<A, B, C, D, E>>>();
+		this.mapBKey = new HashMap<B, List<PentaKey<A, B, C, D, E>>>();
+		this.mapCKey = new HashMap<C, List<PentaKey<A, B, C, D, E>>>();
+		this.mapDKey = new HashMap<D, List<PentaKey<A, B, C, D, E>>>();
+		this.mapOwnKey = new HashMap<E, PentaKey<A, B, C, D, E>>();
+	}
+	
+	public PentaMap(PentaMap<V, A, B, C, D, E> m) {
+		this.map  = new HashMap<PentaKey<A, B, C, D, E>, V>();
+		this.mapAKey = new HashMap<A, List<PentaKey<A, B, C, D, E>>>();
+		this.mapBKey = new HashMap<B, List<PentaKey<A, B, C, D, E>>>();
+		this.mapCKey = new HashMap<C, List<PentaKey<A, B, C, D, E>>>();
+		this.mapDKey = new HashMap<D, List<PentaKey<A, B, C, D, E>>>();
+		this.mapOwnKey = new HashMap<E, PentaKey<A, B, C, D, E>>();
+		this.putAllForCreate(m);
+	}
+
+	private void putAllForCreate(PentaMap<? extends V, A, B, C, D, E> m) {
+		for(Map.Entry<PentaKey<A, B, C, D, E>, ? extends V> e : m.entrySet()){
+			
+			PentaKey<A, B, C, D, E> tKey = e.getKey(); 
+			
+			this.map.put(tKey, e.getValue());
+			 this.mapOwnKey.put(tKey.getOwnKey(), tKey);
+			 
+			 if(!mapAKey.containsKey(tKey.getAKey())){
+				 mapAKey.put(tKey.getAKey(), new ArrayList<PentaKey<A, B, C, D, E>>());
+			 }
+			 if(!mapAKey.get(tKey.getAKey()).contains(tKey)){
+				 mapAKey.get(tKey.getAKey()).add(tKey);	 
+			 }
+			 
+			 if(!mapBKey.containsKey(tKey.getBKey())){
+				 mapBKey.put(tKey.getBKey(), new ArrayList<PentaKey<A, B, C, D, E>>());
+			 }
+			 if(!mapBKey.get(tKey.getBKey()).contains(tKey)){
+				 mapBKey.get(tKey.getBKey()).add(tKey);	 
+			 }
+			 
+			 if(!mapCKey.containsKey(tKey.getCKey())){
+				 mapCKey.put(tKey.getCKey(), new ArrayList<PentaKey<A, B, C, D, E>>());
+			 }
+			 if(!mapCKey.get(tKey.getCKey()).contains(tKey)){
+				 mapCKey.get(tKey.getCKey()).add(tKey);	 
+			 }
+			 if(!mapDKey.containsKey(tKey.getDKey())){
+				 mapDKey.put(tKey.getDKey(), new ArrayList<PentaKey<A, B, C, D, E>>());
+			 }
+			 if(!mapDKey.get(tKey.getDKey()).contains(tKey)){
+				 mapDKey.get(tKey.getDKey()).add(tKey);	 
+			 }
+		}
+	}
+	
+	public List<V> getValuesByAKey(A srcKey){
+		List<V> list = new ArrayList<V>();
+		if(mapAKey.containsKey(srcKey)){
+			for(PentaKey<A, B, C, D, E> tKey : mapAKey.get(srcKey)){
+				list.add(map.get(tKey));
+			}
+		}
+		return list;
+	}
+	
+	public List<V> getValuesByBKey(B tarKey){
+		List<V> list = new ArrayList<V>();
+		if(mapBKey.containsKey(tarKey)){
+			for(PentaKey<A, B, C, D, E> tKey : mapBKey.get(tarKey)){
+				list.add(map.get(tKey));
+			}
+		}
+		return list;
+	}
+	
+	public List<V> getValuesByCKey(C cKey){
+		List<V> list = new ArrayList<V>();
+		if(mapCKey.containsKey(cKey)){
+			for(PentaKey<A, B, C, D, E> tKey : mapCKey.get(cKey)){
+				list.add(map.get(tKey));
+			}
+		}
+		return list;
+	}
+	
+	public List<V> getValuesByDKey(D dKey){
+		List<V> list = new ArrayList<V>();
+		if(mapDKey.containsKey(dKey)){
+			for(PentaKey<A, B, C, D, E> tKey : mapDKey.get(dKey)){
+				list.add(map.get(tKey));
+			}
+		}
+		return list;
+	}
+	
+	public V getValuesByOwnKey(E ownKey){
+		PentaKey<A, B, C, D, E> tKey = mapOwnKey.get(ownKey);
+		if(tKey != null){
+			return this.map.get(tKey);
+		}
+		return null;
+	}
+	
+	public Set<PentaKey<A, B, C, D, E>> keySet(){
+		return this.map.keySet();
+	}
+	
+	public Set<Map.Entry<PentaKey<A, B, C, D, E>, V>> entrySet() {
+		return this.map.entrySet();
+	}	
+	
+	@Override
+	public int size() {
+		return this.map.size();
+	}
+
+	@Override
+	public boolean isEmpty() {
+		return this.map.isEmpty();
+	}
+
+	@Override
+	public boolean containsKey(PentaKey<A, B, C, D, E> key) {
+		return this.map.containsKey(key);
+	}
+
+	@Override
+	public boolean containsValue(Object value) {
+		return this.map.containsValue(value);
+	}
+
+	@Override
+	public V get(PentaKey<A, B, C, D, E> key) {
+		return map.get(key);
+	}
+
+	@Override
+	public V put(PentaKey<A, B, C, D, E> tKey, V value) {
+
+		if(!mapAKey.containsKey(tKey.getAKey())){
+			 mapAKey.put(tKey.getAKey(), new ArrayList<PentaKey<A, B, C, D, E>>());
+		 }
+		 if(!mapAKey.get(tKey.getAKey()).contains(tKey)){
+			 mapAKey.get(tKey.getAKey()).add(tKey);	 
+		 }
+		 
+		 if(!mapBKey.containsKey(tKey.getBKey())){
+			 mapBKey.put(tKey.getBKey(), new ArrayList<PentaKey<A, B, C, D, E>>());
+		 }
+		 if(!mapBKey.get(tKey.getBKey()).contains(tKey)){
+			 mapBKey.get(tKey.getBKey()).add(tKey);	 
+		 }
+		 
+		 if(!mapCKey.containsKey(tKey.getCKey())){
+			 mapCKey.put(tKey.getCKey(), new ArrayList<PentaKey<A, B, C, D, E>>());
+		 }
+		 if(!mapCKey.get(tKey.getCKey()).contains(tKey)){
+			 mapCKey.get(tKey.getCKey()).add(tKey);	 
+		 }
+		 
+		 if(!mapDKey.containsKey(tKey.getDKey())){
+			 mapDKey.put(tKey.getDKey(), new ArrayList<PentaKey<A, B, C, D, E>>());
+		 }
+		 if(!mapDKey.get(tKey.getDKey()).contains(tKey)){
+			 mapDKey.get(tKey.getDKey()).add(tKey);	 
+		 }
+		 
+		 this.mapOwnKey.put(tKey.getOwnKey(), tKey);
+		 return this.map.put(tKey, value);
+	}
+
+	@Override
+	public V remove(PentaKey<A, B, C, D, E> key) {
+		if(mapAKey.containsKey(key.getAKey())){
+			mapAKey.get(key.getAKey()).remove(key);
+		}
+		if(mapBKey.containsKey(key.getBKey())){
+			mapBKey.get(key.getBKey()).remove(key);
+		}
+		if(mapCKey.containsKey(key.getCKey())){
+			mapCKey.get(key.getCKey()).remove(key);
+		}
+		if(mapDKey.containsKey(key.getDKey())){
+			mapDKey.get(key.getDKey()).remove(key);
+		}
+		
+		this.mapOwnKey.remove(key.getOwnKey());
+		return this.map.remove(key);
+	}
+
+	@Override
+	public void clear() {
+		this.map.clear();
+		this.mapAKey.clear();
+		this.mapBKey.clear();
+		this.mapCKey.clear();
+		this.mapDKey.clear();
+		this.mapOwnKey.clear();
+	}
+
+	@Override
+	public Collection<V> values() {
+		return this.map.values();
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/cl/maps/quad/IQuadMap.java	Wed Dec 14 15:49:40 2016 +0100
@@ -0,0 +1,51 @@
+package cl.maps.quad;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+public interface IQuadMap<V, A, B, C, D> {
+
+	int size();
+	
+	boolean isEmpty();
+
+	boolean containsKey(QuadKey<A, B, C, D> key);
+
+	boolean containsValue(Object value);
+	
+	V get(QuadKey<A, B, C, D> key);
+	
+	V put(QuadKey<A, B, C, D> key, V value);
+
+	V remove(QuadKey<A, B, C, D> key);
+
+	//void putAll(Map<? extends K, ? extends V> m);
+
+	void clear();
+
+	Set<QuadKey<A, B, C, D>> keySet();
+
+	Collection<V> values();
+
+	Set<Map.Entry<QuadKey<A, B, C, D>, V>> entrySet();
+
+	boolean equals(Object o);
+
+	/**
+	  * Returns the hash code value for this map.  The hash code of a map is
+	  * defined to be the sum of the hash codes of each entry in the map's
+	  * <tt>entrySet()</tt> view.  This ensures that <tt>m1.equals(m2)</tt>
+	  * implies that <tt>m1.hashCode()==m2.hashCode()</tt> for any two maps
+	  * <tt>m1</tt> and <tt>m2</tt>, as required by the general contract of
+	  * {@link Object#hashCode}.
+	  *
+	  * @return the hash code value for this map
+	  * @see Map.Entry#hashCode()
+	  * @see Object#equals(Object)
+	  * @see #equals(Object)
+	  */
+	int hashCode();
+
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/cl/maps/quad/QuadKey.java	Wed Dec 14 15:49:40 2016 +0100
@@ -0,0 +1,135 @@
+package cl.maps.quad;
+
+public class QuadKey<A, B, C, D> {
+	private A aKey;
+	private B bKey;
+	private C cKey;
+	private D ownKey;
+	
+	public QuadKey(A aKey, B bKey, C cKey, D ownKey){
+		this.aKey = aKey;
+		this.bKey = bKey;
+		this.cKey = cKey;
+		this.ownKey = ownKey;
+	}
+	
+	/*
+	public boolean containsKey(Object key){
+		if(key != null){
+			if(key.equals(aKey) || key.equals(bKey) || key.equals(ownKey)){
+				return true;
+			}
+		}
+		return false;
+	}*/
+	
+
+	public boolean equalsAKey(Object key){
+		if(aKey != null && key != null){
+			return aKey.equals(key);
+		}else if(aKey == null && key == null){
+			return true;
+		}
+		return false;
+	}
+	
+	public boolean equalsBKey(Object key){
+		if(bKey != null && key != null){
+			return bKey.equals(key);
+		}else if(bKey == null && key == null){
+			return true;
+		}
+		return false;
+	}
+	
+	public boolean equalsCKey(Object key){
+		if(cKey != null && key != null){
+			return cKey.equals(key);
+		}else if(cKey == null && key == null){
+			return true;
+		}
+		return false;
+	}
+	
+	public boolean equalsOwnKey(Object key){
+		if(ownKey != null && key != null){
+			return ownKey.equals(key);
+		}else if(ownKey == null && key == null){
+			return true;
+		}
+		return false;
+	}
+	
+	public A getAKey() {
+		return aKey;
+	}
+
+	public void setAKey(A aKey) {
+		this.aKey = aKey;
+	}
+
+	public B getBKey() {
+		return bKey;
+	}
+
+	public void setBKey(B bKey) {
+		this.bKey = bKey;
+	}
+
+	public D getOwnKey() {
+		return ownKey;
+	}
+
+	public void setOwnKey(D ownKey) {
+		this.ownKey = ownKey;
+	}
+	
+	public C getCKey() {
+		return cKey;
+	}
+
+	public void setCKey(C cKey) {
+		this.cKey = cKey;
+	}
+
+	@Override
+	public boolean equals(Object o){
+		if(o instanceof QuadKey){
+			try {
+				QuadKey<A, B, C, D> other = (QuadKey<A, B, C, D>)o;
+				
+				if(this.equalsOwnKey(other.getOwnKey()) &&
+						this.equalsAKey(other.getAKey()) &&
+						this.equalsBKey(other.getBKey()) &&
+						this.equalsCKey(other.getCKey())){
+					return true;
+				}	
+			} catch (Exception e) {}			
+		}
+		return false;
+	}
+	
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((aKey == null) ? 0 : aKey.hashCode());
+		result = prime * result + ((bKey == null) ? 0 : bKey.hashCode());
+		result = prime * result + ((cKey == null) ? 0 : cKey.hashCode());
+		result = prime * result + ((ownKey == null) ? 0 : ownKey.hashCode());
+		
+		return result;
+	}
+
+	@Override
+	public String toString() {
+		if (aKey == null || bKey == null || cKey == null || ownKey == null) {
+			return super.toString();
+		}
+		return "QuadKey [" + 
+			aKey.toString() + ", " + 
+			bKey.toString() + ", " +
+			cKey.toString() + ", " + 
+			ownKey.toString() + "]";
+	}	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/cl/maps/quad/QuadMap.java	Wed Dec 14 15:49:40 2016 +0100
@@ -0,0 +1,191 @@
+package cl.maps.quad;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class QuadMap<V, A, B, C, D> implements IQuadMap<V, A, B, C, D>{
+	
+	private Map<QuadKey<A, B, C, D>, V> map;
+	private Map<A, List<QuadKey<A, B, C, D>>> mapAKey;
+	private Map<B, List<QuadKey<A, B, C, D>>> mapBKey;
+	private Map<C, List<QuadKey<A, B, C, D>>> mapCKey;
+	private Map<D, QuadKey<A, B, C, D>> mapOwnKey;
+	
+	public QuadMap(){
+		this.map  = new HashMap<QuadKey<A, B, C, D>, V>();
+		this.mapAKey = new HashMap<A, List<QuadKey<A, B, C, D>>>();
+		this.mapBKey = new HashMap<B, List<QuadKey<A, B, C, D>>>();
+		this.mapCKey = new HashMap<C, List<QuadKey<A, B, C, D>>>();
+		this.mapOwnKey = new HashMap<D, QuadKey<A, B, C, D>>();
+	}
+	
+	public QuadMap(QuadMap<? extends V, A, B, C, D> m) {
+		this.map  = new HashMap<QuadKey<A, B, C, D>, V>();
+		this.mapAKey = new HashMap<A, List<QuadKey<A, B, C, D>>>();
+		this.mapBKey = new HashMap<B, List<QuadKey<A, B, C, D>>>();
+		this.mapCKey = new HashMap<C, List<QuadKey<A, B, C, D>>>();
+		this.mapOwnKey = new HashMap<D, QuadKey<A, B, C, D>>();
+		this.putAllForCreate(m);
+	}
+
+	private void putAllForCreate(QuadMap<? extends V, A, B, C, D> m) {
+		for(Map.Entry<QuadKey<A, B, C, D>, ? extends V> e : m.entrySet()){
+			QuadKey<A, B, C, D> tKey = e.getKey(); 
+			 this.map.put(tKey, e.getValue());
+			 this.mapOwnKey.put(tKey.getOwnKey(), tKey);
+			 
+			 if(!mapAKey.containsKey(tKey.getAKey())){
+				 mapAKey.put(tKey.getAKey(), new ArrayList<QuadKey<A, B, C, D>>());
+			 }
+			 if(!mapAKey.get(tKey.getAKey()).contains(tKey)){
+				 mapAKey.get(tKey.getAKey()).add(tKey);	 
+			 }
+			 
+			 if(!mapBKey.containsKey(tKey.getBKey())){
+				 mapBKey.put(tKey.getBKey(), new ArrayList<QuadKey<A, B, C, D>>());
+			 }
+			 if(!mapBKey.get(tKey.getBKey()).contains(tKey)){
+				 mapBKey.get(tKey.getBKey()).add(tKey);	 
+			 }
+			 
+			 if(!mapCKey.containsKey(tKey.getCKey())){
+				 mapCKey.put(tKey.getCKey(), new ArrayList<QuadKey<A, B, C, D>>());
+			 }
+			 if(!mapCKey.get(tKey.getCKey()).contains(tKey)){
+				 mapCKey.get(tKey.getCKey()).add(tKey);	 
+			 }
+		}
+	}
+	
+	public List<V> getValuesByAKey(A srcKey){
+		List<V> list = new ArrayList<V>();
+		if(mapAKey.containsKey(srcKey)){
+			for(QuadKey<A, B, C, D> tKey : mapAKey.get(srcKey)){
+				list.add(map.get(tKey));
+			}
+		}
+		return list;
+	}
+	
+	public List<V> getValuesByBKey(B tarKey){
+		List<V> list = new ArrayList<V>();
+		if(mapBKey.containsKey(tarKey)){
+			for(QuadKey<A, B, C, D> tKey : mapBKey.get(tarKey)){
+				list.add(map.get(tKey));
+			}
+		}
+		return list;
+	}
+	
+	public List<V> getValuesByCKey(C cKey){
+		List<V> list = new ArrayList<V>();
+		if(mapCKey.containsKey(cKey)){
+			for(QuadKey<A, B, C, D> tKey : mapCKey.get(cKey)){
+				list.add(map.get(tKey));
+			}
+		}
+		return list;
+	}
+	
+	public V getValuesByOwnKey(D ownKey){
+		QuadKey<A, B, C, D> tKey = mapOwnKey.get(ownKey);
+		if(tKey != null){
+			return this.map.get(tKey);
+		}
+		return null;
+	}
+	
+	public Set<QuadKey<A, B, C, D>> keySet(){
+		return this.map.keySet();
+	}
+	
+	public Set<Map.Entry<QuadKey<A, B, C, D>, V>> entrySet() {
+		return this.map.entrySet();
+	}	
+	
+	@Override
+	public int size() {
+		return this.map.size();
+	}
+
+	@Override
+	public boolean isEmpty() {
+		return this.map.isEmpty();
+	}
+
+	@Override
+	public boolean containsKey(QuadKey<A, B, C, D> key) {
+		return this.map.containsKey(key);
+	}
+
+	@Override
+	public boolean containsValue(Object value) {
+		return this.map.containsValue(value);
+	}
+
+	@Override
+	public V get(QuadKey<A, B, C, D> key) {
+		return map.get(key);
+	}
+
+	@Override
+	public V put(QuadKey<A, B, C, D> tKey, V value) {
+
+		if(!mapAKey.containsKey(tKey.getAKey())){
+			 mapAKey.put(tKey.getAKey(), new ArrayList<QuadKey<A, B, C, D>>());
+		 }
+		 if(!mapAKey.get(tKey.getAKey()).contains(tKey)){
+			 mapAKey.get(tKey.getAKey()).add(tKey);	 
+		 }
+		 
+		 if(!mapBKey.containsKey(tKey.getBKey())){
+			 mapBKey.put(tKey.getBKey(), new ArrayList<QuadKey<A, B, C, D>>());
+		 }
+		 if(!mapBKey.get(tKey.getBKey()).contains(tKey)){
+			 mapBKey.get(tKey.getBKey()).add(tKey);	 
+		 }
+		 
+		 if(!mapCKey.containsKey(tKey.getCKey())){
+			 mapCKey.put(tKey.getCKey(), new ArrayList<QuadKey<A, B, C, D>>());
+		 }
+		 if(!mapCKey.get(tKey.getCKey()).contains(tKey)){
+			 mapCKey.get(tKey.getCKey()).add(tKey);	 
+		 }
+		 
+		 this.mapOwnKey.put(tKey.getOwnKey(), tKey);
+		 return this.map.put(tKey, value);
+	}
+
+	@Override
+	public V remove(QuadKey<A, B, C, D> key) {
+		if(mapAKey.containsKey(key.getAKey())){
+			mapAKey.get(key.getAKey()).remove(key);
+		}
+		if(mapBKey.containsKey(key.getBKey())){
+			mapBKey.get(key.getBKey()).remove(key);
+		}
+		if(mapCKey.containsKey(key.getCKey())){
+			mapCKey.get(key.getCKey()).remove(key);
+		}
+		this.mapOwnKey.remove(key.getOwnKey());
+		return this.map.remove(key);
+	}
+
+	@Override
+	public void clear() {
+		this.map.clear();
+		this.mapAKey.clear();
+		this.mapBKey.clear();
+		this.mapCKey.clear();
+		this.mapOwnKey.clear();
+	}
+
+	@Override
+	public Collection<V> values() {
+		return this.map.values();
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/cl/maps/triple/ITripleMap.java	Wed Dec 14 15:49:40 2016 +0100
@@ -0,0 +1,52 @@
+package cl.maps.triple;
+
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+public interface ITripleMap<V, A, B, C> {
+
+	int size();
+	
+	boolean isEmpty();
+
+	boolean containsKey(TripleKey<A, B, C> key);
+
+	boolean containsValue(Object value);
+	
+	V get(TripleKey<A, B, C> key);
+	
+	V put(TripleKey<A, B, C> key, V value);
+
+	V remove(TripleKey<A, B, C> key);
+
+	//void putAll(Map<? extends K, ? extends V> m);
+
+	void clear();
+
+	Set<TripleKey<A, B, C>> keySet();
+
+	Collection<V> values();
+
+	Set<Map.Entry<TripleKey<A, B, C>, V>> entrySet();
+
+	boolean equals(Object o);
+
+	/**
+	  * Returns the hash code value for this map.  The hash code of a map is
+	  * defined to be the sum of the hash codes of each entry in the map's
+	  * <tt>entrySet()</tt> view.  This ensures that <tt>m1.equals(m2)</tt>
+	  * implies that <tt>m1.hashCode()==m2.hashCode()</tt> for any two maps
+	  * <tt>m1</tt> and <tt>m2</tt>, as required by the general contract of
+	  * {@link Object#hashCode}.
+	  *
+	  * @return the hash code value for this map
+	  * @see Map.Entry#hashCode()
+	  * @see Object#equals(Object)
+	  * @see #equals(Object)
+	  */
+	int hashCode();
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/cl/maps/triple/TripleKey.java	Wed Dec 14 15:49:40 2016 +0100
@@ -0,0 +1,109 @@
+package cl.maps.triple;
+
+/**
+ * Unique ownKey. SrcKey and bKey not unique.
+ * 
+ * @author jurzua
+ * 
+ */
+public class TripleKey<A, B, C> {
+
+	private A aKey;
+	private B bKey;
+	private C ownKey;
+
+	public TripleKey(A aKey, B label, C ownKey) {
+		this.aKey = aKey;
+		this.bKey = label;
+		this.ownKey = ownKey;
+	}
+
+	public boolean equalsAKey(A key) {
+		if (aKey != null && key != null) {
+			return aKey.equals(key);
+		} else if (aKey == null && key == null) {
+			return true;
+		}
+		return false;
+	}
+
+	public boolean equalsBKey(B key) {
+		if (bKey != null && key != null) {
+			return bKey.equals(key);
+		} else if (bKey == null && key == null) {
+			return true;
+		}
+		return false;
+	}
+
+	public boolean equalsOwnKey(C key) {
+		if (ownKey != null && key != null) {
+			return ownKey.equals(key);
+		} else if (ownKey == null && key == null) {
+			return true;
+		}
+		return false;
+	}
+
+	public A getAKey() {
+		return aKey;
+	}
+
+	public void setAKey(A aKey) {
+		this.aKey = aKey;
+	}
+
+	public B getBKey() {
+		return bKey;
+	}
+
+	public void setBKey(B bKey) {
+		this.bKey = bKey;
+	}
+
+	public C getOwnKey() {
+		return ownKey;
+	}
+
+	public void setOwnKey(C ownKey) {
+		this.ownKey = ownKey;
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (o instanceof TripleKey) {
+			try {
+				TripleKey<A, B, C> other = (TripleKey<A, B, C>) o;
+
+				if (this.equalsOwnKey(other.getOwnKey())
+						&& this.equalsAKey(other.getAKey())
+						&& this.equalsBKey(other.getBKey())) {
+					return true;
+				}
+			} catch (Exception e) {
+			}
+		}
+		return false;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((aKey == null) ? 0 : aKey.hashCode());
+		result = prime * result + ((bKey == null) ? 0 : bKey.hashCode());
+		result = prime * result + ((ownKey == null) ? 0 : ownKey.hashCode());
+		
+		return result;
+	}
+
+	@Override
+	public String toString() {
+		if (aKey == null || bKey == null || ownKey == null) {
+			return super.toString();
+		}
+		return "TripleKey [" + aKey.toString() + ", " + bKey.toString() + ", "
+				+ ownKey.toString() + "]";
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/cl/maps/triple/TripleMap.java	Wed Dec 14 15:49:40 2016 +0100
@@ -0,0 +1,169 @@
+package cl.maps.triple;
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class TripleMap<V, A, B, C> implements ITripleMap<V, A, B, C>{
+	
+	private Map<TripleKey<A, B, C>, V> map;
+	private Map<A, List<TripleKey<A, B, C>>> mapAKey;
+	private Map<B, List<TripleKey<A, B, C>>> mapBKey;
+	private Map<C, TripleKey<A, B, C>> mapOwnKey;
+	
+	public TripleMap(){
+		this.map  = new HashMap<TripleKey<A, B, C>, V>();
+		this.mapAKey = new HashMap<A, List<TripleKey<A, B, C>>>();
+		this.mapBKey = new HashMap<B, List<TripleKey<A, B, C>>>();
+		this.mapOwnKey = new HashMap<C, TripleKey<A, B, C>>();
+	}
+	
+	public TripleMap(TripleMap<? extends V, A, B, C> m) {
+		this.map  = new HashMap<TripleKey<A, B, C>, V>();
+		this.mapAKey = new HashMap<A, List<TripleKey<A, B, C>>>();
+		this.mapBKey = new HashMap<B, List<TripleKey<A, B, C>>>();
+		this.mapOwnKey = new HashMap<C, TripleKey<A, B, C>>();
+		this.putAllForCreate(m);
+	}
+
+	private void putAllForCreate(TripleMap<? extends V, A, B, C> m) {
+		for(Map.Entry<TripleKey<A, B, C>, ? extends V> e : m.entrySet()){
+			TripleKey<A, B, C> tKey = e.getKey(); 
+			 this.map.put(tKey, e.getValue());
+			 this.mapOwnKey.put(tKey.getOwnKey(), tKey);
+			 
+			 if(!mapAKey.containsKey(tKey.getAKey())){
+				 mapAKey.put(tKey.getAKey(), new ArrayList<TripleKey<A, B, C>>());
+			 }
+			 if(!mapAKey.get(tKey.getAKey()).contains(tKey)){
+				 mapAKey.get(tKey.getAKey()).add(tKey);
+			 }
+			 
+			 if(!mapBKey.containsKey(tKey.getBKey())){
+				 mapBKey.put(tKey.getBKey(), new ArrayList<TripleKey<A, B, C>>());
+			 }
+			 if(!mapBKey.get(tKey.getBKey()).contains(tKey)){
+				 mapBKey.get(tKey.getBKey()).add(tKey);
+			 }
+		}
+	}
+	
+	public List<V> getValuesByAKey(A srcKey){
+		List<V> list = new ArrayList<V>();
+		if(mapAKey.containsKey(srcKey)){
+			for(TripleKey<A, B, C> tKey : mapAKey.get(srcKey)){
+				list.add(map.get(tKey));
+			}
+		}
+		return list;
+	}
+	
+	public List<V> getValuesByBKey(B tarKey){
+		List<V> list = new ArrayList<V>();
+		if(mapBKey.containsKey(tarKey)){
+			for(TripleKey<A, B, C> tKey : mapBKey.get(tarKey)){
+				list.add(map.get(tKey));
+			}
+		}
+		return list;
+	}
+	
+	public V getValuesByOwnKey(C ownKey){
+		TripleKey<A, B, C> tKey = mapOwnKey.get(ownKey);
+		if(tKey != null){
+			return this.map.get(tKey);
+		}
+		return null;
+	}
+	
+	public Set<TripleKey<A, B, C>> keySet(){
+		return this.map.keySet();
+	}
+	
+	public Set<Map.Entry<TripleKey<A, B, C>, V>> entrySet() {
+		return this.map.entrySet();
+	}	
+	
+	@Override
+	public int size() {
+		return this.map.size();
+	}
+
+	@Override
+	public boolean isEmpty() {
+		return this.map.isEmpty();
+	}
+
+	@Override
+	public boolean containsKey(TripleKey<A, B, C> key) {
+		return this.map.containsKey(key);
+	}
+
+	@Override
+	public boolean containsValue(Object value) {
+		return this.map.containsValue(value);
+	}
+
+	@Override
+	public V get(TripleKey<A, B, C> key) {
+		return map.get(key);
+	}
+
+	@Override
+	public V put(TripleKey<A, B, C> tKey, V value) {
+		if(!mapAKey.containsKey(tKey.getAKey())){
+			 mapAKey.put(tKey.getAKey(), new ArrayList<TripleKey<A, B, C>>());
+		}
+		if(!mapAKey.get(tKey.getAKey()).contains(tKey)){
+			mapAKey.get(tKey.getAKey()).add(tKey);
+		}
+
+		if(!mapBKey.containsKey(tKey.getBKey())){
+			mapBKey.put(tKey.getBKey(), new ArrayList<TripleKey<A, B, C>>());
+		}
+		if(!mapBKey.get(tKey.getBKey()).contains(tKey)){
+			mapBKey.get(tKey.getBKey()).add(tKey);
+		}
+		
+		this.mapOwnKey.put(tKey.getOwnKey(), tKey);
+		return this.map.put(tKey, value);
+	}
+
+	@Override
+	public V remove(TripleKey<A, B, C> key) {
+		if(mapAKey.containsKey(key.getAKey())){
+			mapAKey.get(key.getAKey()).remove(key);
+		}
+		if(mapBKey.containsKey(key.getBKey())){
+			mapBKey.get(key.getBKey()).remove(key);
+		}
+		this.mapOwnKey.remove(key.getOwnKey());
+		
+		int hashCodeInput = key.hashCode();
+		System.out.println(hashCodeInput);
+		if(map.size() == 1){
+			Object uu = new ArrayList<TripleKey<A, B, C>>(map.keySet()).get(0);
+			int hashCode2 = uu.hashCode();
+			System.out.println(hashCode2);
+		}
+		
+		return this.map.remove(key);
+	}
+
+	@Override
+	public void clear() {
+		this.map.clear();
+		this.mapAKey.clear();
+		this.mapBKey.clear();
+		this.mapOwnKey.clear();
+	}
+
+	@Override
+	public Collection<V> values() {
+		return this.map.values();
+	}
+}