Best Practices for Using Multi Level HashMap in Java

anzaan picture anzaan · Jul 15, 2015 · Viewed 10.4k times · Source

We have a situation where we are ending up using multi-level hash maps; that is, a hash map inside of a hash map, three or four levels deep.

Instinctively this felt wrong somewhere. I have read posts here that talks about how to iterate/use a multi-level hash map, but hardly any of them say what is the best practice for this.

Why are multi level hash maps bad, and what would be the better design, if any?

Here is the sample design of multi-level hash maps that we have:

Map<String, Object1> map1;

class Object1 {
    String version;
    Map<String,Object2> map2;
}

class Object2 {
    Map<String,List<Object3>> map4;
    Map<String,String> map5;
}

Answer

Makoto picture Makoto · Jul 15, 2015

As long as they're properly abstracted, it's not that big of a deal, but you lead yourself down some nasty rabbit holes in terms of readability. Without abstraction, maintaining this becomes a nightmare that no developer would wish on another.

Essentially, what you're creating is a table of sorts; the first key is the primary key to gain access to further columns. On a simple one, two, or three-level design, this isn't terrible; you need three keys to get a single value. Provided that there's a convenient way to access it, like the below, it's not a terrible idea (although there are far better out there).

public interface Table<K1, K2, K3, V> {
    V get(K1 key1, K2 key2, K3 key3);
}

...However, it all depends on what you're actually doing with that data structure. If you find yourself attempting to iterate intermediate keys for values (that is, you're looking at Key 3 for the collection of all values between it and Key 5), you've got to rethink your business logic at that point. The data structure provided isn't flexible enough to handle all cases; more or less, it's used for simplistic indexing based on a set of values.

Alternatively, one could look into a Guava Table, as that does the same sort of thing, with a better interface to it (something like the one I have above).