PROBLEM
HashMap is great to perform a simple lookup, for example:-
Map<String, String> map = new HashMap<String, String>();
map.put("key", "mike");
String value = map.get("key"); // "mike"
However, what if we need 2 keys to lookup a value? For example, we need “key1” + “key2” in order to lookup “mike”.
SOLUTION 1: Create combo key
You can combine the keys to create a unique key:-
Map<String, String> map = new HashMap<String, String>();
map.put("key1|key2", "mike");
String value = map.get("key1|key2"); // "mike"
Assuming if the keys are just characters, this works fine. However, this solution might not work too well if the keys are objects, like Person object, etc.
SOLUTION 2: Create key as an object
In this solution, we leverage Apache Commons’ MultiKey to create the combo key:-
Map<MultiKey, String> map = new HashMap<MultiKey, String>();
map.put(new MultiKey("key1", "key2"), "mike");
String value = map.get(new MultiKey("key1", "key2")); // "mike"
This solution works a little better than the first solution, but the code looks just plain ugly to read.
SOLUTION 3: Using Map of Map
In this solution, we use Map of Map to accomplish the 2-key lookup:-
Map<String, Map<String, String>> map = new HashMap<String, Map<String, String>>();
Map<String, String> innnerMap = new HashMap<String, String>();
innnerMap.put("key2", "mike");
map.put("key1", innnerMap);
String value = map.get("key1").get("key2"); // "mike"
This solution obviously offers tons of flexibility, but it is shit difficult to read… and sadly, I myself implemented something like this in the past. In my opinion, this solution is too complicated for what we are trying to achieve here. We also have to worry about whether map.get(firstKey) will return null, which may cause NullPointerException if we chain the call to lookup the second key.
SOLUTION 4: Using HashBasedTable
The most elegant solution in my opinion is to utilize Google Guava’s HashBasedTable:-
HashBasedTable<String, String, String> hashBasedTable = HashBasedTable.create();
hashBasedTable.put("key1", "key2", "mike");
String value = hashBasedTable.get("key1", "key2"); // "mike"
This is probably the cleanest solution to perform 2-key lookup. Based on the documentation, HashBasedTable itself is using Map of Map under the cover.
Leave a Reply