This seems like a good start to a multi key map implementation.
Edited to add a removeElement method, and to save and return a List of values.
package com.ggl.testing;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class MultiMap<K, V> {
private static long sequence = 0;
private Map<K, Long> key1Map;
private Map<K, Long> key2Map;
private Map<Long, List<V>> valueMap;
public MultiMap() {
this.key1Map = new HashMap<>();
this.key2Map = new HashMap<>();
this.valueMap = new HashMap<>();
}
public void addElement(K key1, K key2, V value) {
boolean key1boolean = key1Map.containsKey(key1);
boolean key2boolean = key2Map.containsKey(key2);
boolean key3boolean = key1Map.containsKey(key2);
boolean key4boolean = key2Map.containsKey(key1);
if (key1boolean && key2boolean) {
Long key1Value = key1Map.get(key1);
Long key2Value = key2Map.get(key2);
updateValue(key1, key2, key1Value, key2Value, value);
} else if (key3boolean && key4boolean) {
Long key1Value = key1Map.get(key2);
Long key2Value = key2Map.get(key1);
updateValue(key1, key2, key1Value, key2Value, value);
} else if (key1boolean || key4boolean) {
String s = displayDuplicateError(key1);
throw new IllegalStateException(s);
} else if (key2boolean || key3boolean) {
String s = displayDuplicateError(key2);
throw new IllegalStateException(s);
} else {
createValue(key1, key2, value);
}
}
private void createValue(K key1, K key2, V value) {
Long newKeyValue = sequence++;
key1Map.put(key1, newKeyValue);
key2Map.put(key2, newKeyValue);
List<V> values = new ArrayList<>();
values.add(value);
valueMap.put(newKeyValue, values);
}
private void updateValue(K key1, K key2, Long key1Value, Long key2Value,
V value) {
if (key1Value.equals(key2Value)) {
List<V> values = valueMap.get(key1Value);
values.add(value);
valueMap.put(key1Value, values);
} else {
String s = displayMismatchError(key1, key2);
throw new IllegalStateException(s);
}
}
private String displayMismatchError(K key1, K key2) {
return "Keys " + key1.toString() + " & " + key2.toString()
+ " have a different internal key.";
}
private String displayDuplicateError(K key) {
return "Key " + key.toString() + " is part of another key pair";
}
public List<V> getElement(K key) {
if (key1Map.containsKey(key)) {
return valueMap.get(key1Map.get(key));
}
if (key2Map.containsKey(key)) {
return valueMap.get(key2Map.get(key));
}
return null;
}
public boolean removeElement(K key) {
if (key1Map.containsKey(key)) {
Long key1Value = key1Map.get(key);
Set<Entry<K, Long>> entrySet = key2Map.entrySet();
K key2 = getOtherKey(key1Value, entrySet);
valueMap.remove(key1Value);
key1Map.remove(key);
key2Map.remove(key2);
return true;
} else if (key2Map.containsKey(key)) {
Long key2Value = key2Map.get(key);
Set<Entry<K, Long>> entrySet = key1Map.entrySet();
K key1 = getOtherKey(key2Value, entrySet);
valueMap.remove(key2Value);
key1Map.remove(key1);
key2Map.remove(key);
return true;
}
return false;
}
private K getOtherKey(Long key1Value, Set<Entry<K, Long>> entrySet) {
Iterator<Entry<K, Long>> iter = entrySet.iterator();
K key = null;
while (iter.hasNext() && key == null) {
Entry<K, Long> entry = iter.next();
if (entry.getValue().equals(key1Value)) {
key = entry.getKey();
}
}
return key;
}
public static void main(String[] args) {
MultiMap<String, String> multiMap = new MultiMap<>();
try {
multiMap.addElement("one", "two", "numbers");
multiMap.addElement("alpha", "beta", "greek alphabet");
multiMap.addElement("beta", "alpha", "alphabet");
multiMap.addElement("iron", "oxygen", "elements");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(Arrays.toString(multiMap.getElement("iron")
.toArray()));
System.out.println(Arrays.toString(multiMap.getElement("beta")
.toArray()));
System.out.println(multiMap.removeElement("two"));
}
}