Implement a Map with multiple keys (MultiKeyMap) in Java
This post will implement MultiKeyMap in plain Java and cover its possible implementations in Apache Commons Collection and Guava library. Basically, we need a map implementation that uses multiple keys to map the value in Java.
1. Using Plain Java
The idea is to construct a custom class Key, which consists of all keys, and use an instance of the Key class in our map as a key to map the value. The Key class should override equals() and hashCode() methods to test equality on hash-based map. This is demonstrated below for two keys. Note that we can easily extend the solution to any number of keys.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
import java.util.HashMap; import java.util.Map; class Key<K1, K2> { public K1 key1; public K2 key2; public Key(K1 key1, K2 key2) { this.key1 = key1; this.key2 = key2; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } Key key = (Key) o; if (key1 != null ? !key1.equals(key.key1) : key.key1 != null) { return false; } if (key2 != null ? !key2.equals(key.key2) : key.key2 != null) { return false; } return true; } @Override public int hashCode() { int result = key1 != null ? key1.hashCode() : 0; result = 31 * result + (key2 != null ? key2.hashCode() : 0); return result; } @Override public String toString() { return "[" + key1 + ", " + key2 + "]"; } } class Main { public static void main(String[] args) { // Create a `HashMap` with `Key` as key Map<Key, String> multiKeyMap = new HashMap<>(); // [key1, key2] -> value1 Key k12 = new Key("key1", "key2"); multiKeyMap.put(k12, "value1"); // [key3, key4] -> value2 Key k34 = new Key("key3", "key4"); multiKeyMap.put(k34, "value2"); // print multikey map System.out.println(multiKeyMap); // print value corresponding to key1 and key2 System.out.println(multiKeyMap.get(k12)); } } |
Output:
{[key1, key2]=value1, [key3, key4]=value2}
value1
2. Using Apache Commons Collections
We can also use Apache Commons Collection, which provides an efficient map implementation MultiKeyMap that maps multiple keys to a value. MultiKeyMap provides get, containsKey, put, and remove for individual keys.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import org.apache.commons.collections4.map.LinkedMap; import org.apache.commons.collections4.map.MultiKeyMap; class Main { public static void main(String[] args) { // creates an ordered map MultiKeyMap multiKeyMap = MultiKeyMap.multiKeyMap(new LinkedMap()); // [key1, key2] -> value1 multiKeyMap.put("key1", "key2", "value1"); // [key3, key4] -> value2 multiKeyMap.put("key3", "key4", "value2"); // print multikey map System.out.println(multiKeyMap); // print value corresponding to key1 and key2 System.out.println(multiKeyMap.get("key1", "key2")); } } |
Output:
{MultiKey[key1, key2]=value1, MultiKey[key3, key4]=value2}
value1
3. Using Google’s Guava
There are several ways to accomplish this with Google’s Guava library. An elegant solution is to use Guava’s Table interface, which associates an ordered pair of keys, called a row key and a column key, with a single value.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import com.google.common.collect.HashBasedTable; import com.google.common.collect.Table; class Main { public static void main(String[] args) { // create a map Table<String, String, String> table = HashBasedTable.create(); // [key1, key2] -> value1 table.put("key1", "key2", "value1"); // [key3, key4] -> value2 table.put("key3", "key4", "value2"); // print multikey map System.out.println(table); // print value corresponding to key1 and key2 System.out.println(table.get("key1", "key2")); } } |
Output:
{key1={key2=value1}, key3={key4=value2}}
value1
We can also use ImmutableList to build your keys in order, as shown below:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
import com.google.common.collect.ImmutableList; import com.google.common.collect.Maps; import java.util.Map; class Main { public static void main(String[] args) { // Create a map Map<ImmutableList<String>, String> listKeyMap = Maps.newHashMap(); // [key1, key2] -> value1 listKeyMap.put(ImmutableList.of("key1", "key2"), "value1"); // [key3, key4] -> value2 listKeyMap.put(ImmutableList.of("key3", "key4"), "value2"); // print multikey map System.out.println(listKeyMap); // print value corresponding to key1 and key2 System.out.println(listKeyMap.get(ImmutableList.of("key1", "key2"))); } } |
Output:
{[key1, key2]=value1, [key3, key4]=value2}
value1
That’s all about MultiKeyMap implementation in Java.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)