17

I have some code with Map<String, Map<String, String>> objects, which works (it is instantiated as a HashMap of HashMaps), but I wonder whether there is a better way to represent this data structure in Guava.

I have considered Multimap, but while there is ListMultimap and SetMultimap in Guava, I have found no "MapMultimap".

I have also checked Table, which seems to be more like it, but its name is making me uncomfortable: what I have is definitely not a table but a tree. (There is no overlap between the second keys)

Is there a better Guava alternative or should I stick with Map<String, Map<String, String>>?

sebkur
  • 658
  • 2
  • 9
  • 18
WannaKnow
  • 1,155
  • 2
  • 11
  • 18
  • 1
    How does the inner `Map` look like? What about replacing it with a proper class, so you'd have a `Map` instead? – Philipp Reichart Feb 01 '13 at 11:43
  • @Philipp Reichart: Then my SomeObject needs to have an internal Map, so I don't see how my code would become simpler... – WannaKnow Feb 01 '13 at 11:47
  • 1
    That's why I asked how the inner Maps looks like: If they all have the same keys (e.g. `"firstName"`, `"lastName"`, ...), you can replace them with instances of a class like `Person { String firstName; String lastName; ... }`. If every inner Map is different, this of course won't work. – Philipp Reichart Feb 01 '13 at 11:51
  • @Philipp Reichart: I see. The inner maps are different and not related. – WannaKnow Feb 01 '13 at 12:38

2 Answers2

24

Table seems well suited for your need. But make sure you choose the proper implementation. In particular, if your second keys are all distinct (the columns in the table) the resulting table will be sparse and you should take that into account to manage memory usage.

So you should avoid the ArrayTable, but can use any of the other implementations. Note that the docs mention that ImmutableTable has optimized implementations for sparser and denser data sets.

If your Table is constructed at once, you can use an ImmutableTable.Builder and benefit from this optimisation as well as simplify your life if the table is shared among several threads.

sebkur
  • 658
  • 2
  • 9
  • 18
assylias
  • 321,522
  • 82
  • 660
  • 783
11

Take a look at Guava's Table interface.

Its documentation example seems to overlap quite a bit with your use-case:

Typically, when you are trying to index on more than one key at a time, you will wind up with something like Map<FirstName, Map<LastName, Person>>, which is ugly and awkward to use. Guava provides a new collection type, Table, which supports this use case for any "row" type and "column" type.

sebkur
  • 658
  • 2
  • 9
  • 18
Henrik Aasted Sørensen
  • 6,966
  • 11
  • 51
  • 60