如何在嵌套的 ArrayListMultimap 中获取值
How to get the value in a nested `ArrayListMultimap`
我有以下嵌套代码 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"));
对于 doubleMultiMap.get("D123")
我得到的结果是 [{1=[ABC, XYZ], 2=[BCD]}]
但是如何获取键的值 D123, 1
。我尝试使用 (doubleMultiMap.get("D123")).get(1)
但它不受支持。
更新:
我想要实现的是如下所示。如果嵌套 Multimap
不理想,我可以使用什么替代方案?
实际上,get
returns 是 Collection
(在您的情况下是 Multimap
)。 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.
要获取嵌套的 Multimap,请执行以下操作:
Iterator<Multimap<Integer, String>> iter = doubleMultiMap.get("D123").iterator();
Multimap<Integer, String> nested = iter.next();
如果您不需要 Table
特定的方法,例如行或列访问(看起来您不需要,因为您想要访问 D123, 1
),Multimap
是解决方案。使用适当的 hashCode
和 equals
创建简单的 class 存储字符串和整数,并正常使用 multimap。假设你的复合键 class 名称是 Key
(你应该想到更好的)你应该能够做这样的事情:
//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");
如果您需要访问 by row or by column(例如,获取列 2
的完整映射,在您的情况下将具有键 "D123"
和 "J123"
),那么您可能想要解决 Table<String, Integer, List<String>>
并注意根据需要在 table 值中创建列表(遗憾的是,Table
界面中没有 computeIfAbsent
)。
第三个选项是在 this Guava issue 中讨论 Multitable
,正如@SeanPatrickFloyd 在上面的评论中提到的那样。
我有以下嵌套代码 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"));
对于 doubleMultiMap.get("D123")
我得到的结果是 [{1=[ABC, XYZ], 2=[BCD]}]
但是如何获取键的值 D123, 1
。我尝试使用 (doubleMultiMap.get("D123")).get(1)
但它不受支持。
更新:
我想要实现的是如下所示。如果嵌套 Multimap
不理想,我可以使用什么替代方案?
实际上,get
returns 是 Collection
(在您的情况下是 Multimap
)。 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.
要获取嵌套的 Multimap,请执行以下操作:
Iterator<Multimap<Integer, String>> iter = doubleMultiMap.get("D123").iterator();
Multimap<Integer, String> nested = iter.next();
如果您不需要 Table
特定的方法,例如行或列访问(看起来您不需要,因为您想要访问 D123, 1
),Multimap
是解决方案。使用适当的 hashCode
和 equals
创建简单的 class 存储字符串和整数,并正常使用 multimap。假设你的复合键 class 名称是 Key
(你应该想到更好的)你应该能够做这样的事情:
//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");
如果您需要访问 by row or by column(例如,获取列 2
的完整映射,在您的情况下将具有键 "D123"
和 "J123"
),那么您可能想要解决 Table<String, Integer, List<String>>
并注意根据需要在 table 值中创建列表(遗憾的是,Table
界面中没有 computeIfAbsent
)。
第三个选项是在 this Guava issue 中讨论 Multitable
,正如@SeanPatrickFloyd 在上面的评论中提到的那样。