S.Dan
S.Dan

Reputation: 1912

How to get the value in a nested `ArrayListMultimap`

I have the following code for a nested ArrayListMultimap:

    Multimap<String, Multimap<Integer, String>> doubleMultiMap = ArrayListMultimap.create();
    Multimap<Integer, String> doc = ArrayListMultimap.create();
    doc.put(1, "ABC");
    doc.put(2, "BCD");
    doc.put(1, "XYZ");
    doubleMultiMap.put("D123", doc);

    doc = ArrayListMultimap.create();
    doc.put(1, "John");
    doc.put(2, "Jane");
    doc.put(2, "George");
    doubleMultiMap.put("J123", doc);
    System.out.println(doubleMultiMap.get("D123")); 

For doubleMultiMap.get("D123") I get the result as [{1=[ABC, XYZ], 2=[BCD]}]

But how to get the value for keys D123, 1. I tried to use (doubleMultiMap.get("D123")).get(1) but it is not supported.

Update: What I'm trying to achieve is something like below. If nested Multimap is not ideal, what alternative could I use?

enter image description here

Upvotes: 0

Views: 1378

Answers (2)

Grzegorz Rożniecki
Grzegorz Rożniecki

Reputation: 28015

If you don't need Table-specific methods like row or column access (and it seems you don't, since you want to access D123, 1), compound key for Multimap is the solution. Create simple class storing string and integer with proper hashCode and equals and use multimap normally. Assuming your compound key class name is Key (you should think of better one) you should be able to do something like this:

//given
ListMultimap<Key, String> multimap = ArrayListMultimap.create(); // note ListMultimap
multimap.put(new Key("D123", 1), "ABC");
multimap.put(new Key("D123", 2), "BCD");
multimap.put(new Key("D123", 1), "XYZ");
multimap.put(new Key("J123", 1), "John");
multimap.put(new Key("J123", 2), "Jane");
multimap.put(new Key("J123", 2), "George");
//when
List<String> values = multimap.get(new Key("D123", 1));
//then
assertThat(values).containsExactly("ABC", "XYZ");

If you need to access by row or by column (ex. get complete mapping of column 2 which in your case would have keys "D123" and "J123"), then you may want to settle with Table<String, Integer, List<String>> and take care of creating lists in table values on demand (sadly, there's no computeIfAbsent in Table interface).

Third option would be to discuss Multitable in this Guava issue, as mentioned by @SeanPatrickFloyd in the comment above.

Upvotes: 1

DPM
DPM

Reputation: 2030

Actually, what get returns is a Collection (of Multimap in your case). Take a look:

Collection get(@Nullable K key)

Returns a view collection of the values associated with key in this multimap, if any. Note that when containsKey(key) is false, this returns an empty collection, not null.

Changes to the returned collection will update the underlying multimap, and vice versa.

To get the nested Multimap do this:

Iterator<Multimap<Integer, String>> iter = doubleMultiMap.get("D123").iterator();
Multimap<Integer, String> nested = iter.next();

Upvotes: 1

Related Questions