这大致是使用Table 接口的方式,尽管我会使用firstNonNull(T, T) 来避免调用 get 两次:
Table<String, String, Integer> table = HashBasedTable.create();
table.put("AS", "X", 2);
// with null check
table.put("AS", "BS", Objects.firstNonNull(table.get("AS", "BS"), 0) + 123);
System.out.println(table);
// prints: {AS={BS=123, X=2}}
另一方面,如果您真的不需要Table 接口和/或计数对您来说更重要(并且数字不是负数),请考虑使用Map<String, Multiset<String>。获取多集时空检查会更痛苦,但添加元素会更容易(因为Multiset 的功能):
Map<String, Multiset<String>> mapWithMultiset = new HashMap<>();
// create new multiset to be put as value
HashMultiset<String> x = HashMultiset.create();
x.add("X", 2);
mapWithMultiset.put("AS", x);
// this feels dirty
if (!mapWithMultiset.containsKey("AS")) {
mapWithMultiset.put("AS", HashMultiset.<String>create());
}
mapWithMultiset.get("AS").add("BS", 123);
System.out.println(mapWithMultiset);
// prints: {AS=[BS x 123, X x 2]}
看来你真的需要像 MultisetMultimap aka BagMultimap 这样的东西:
-
Guava 中不存在,
- 会为您节省脏东西。
它可能看起来像这样,尽管命名会变得很棘手,并且 Map / Collection 中的 put / add 方法的使用会令人困惑(明确免责声明:没有比如MultisetMultimap):
MultisetMultimap<String, String> multisetMultimap = HashMultisetMultimap.create();
multisetMultimap.add("AS", "X", 2);
multisetMultimap.add("AS", "BS", 123);
System.out.println(mapWithMultiset);
// should print: {AS=[BS x 123, X x 2]}
(如果您对此解决方案感兴趣,您应该使用new issue on Github。如果 Google 内部的 Guava 中有类似的东西,也许一些 Guava 开发人员可以回答。)