【问题标题】:Convenience class for handling Map<K, List<V>> [duplicate]处理 Map<K, List<V>> 的便利类 [重复]
【发布时间】:2016-12-23 17:57:15
【问题描述】:

在我从事的各种项目中,我发现了一个类似的模式

Map<Integer, List<String>> listMap = new HashMap<Integer, List<String>>();

public void addValue(Integer key, String value) {
    if (!listMap.containsKey(key)) {
        listMap.put(key, new ArrayList<String>());
    }
    listMap.get(key).add(value);
}

填充具有Lists 作为值的地图。

由于这是一种常见的模式,我想知道标准库中是否没有一些便利类或类似番石榴之类的东西来管理向该结构添加和删除值。

【问题讨论】:

  • Spring 有MultiValueMap,但没有标准。
  • 你看过 Guava 文档吗? interface Multimap
  • 还有 Apache Commons Collections - interface MultiMap
  • @AndyTurner, ArrayList::new 不正确。看我的回答。
  • @Kayaman 投票重新开放,因为这提供了比其他帖子中更高质量的问题和答案(如果我可以这么说的话)。更不用说它没有公认的答案。

标签: java list dictionary collections guava


【解决方案1】:

Guava 提供Multimap,非常适合您的目的:

ListMultimap<Integer, String> listMap = ArrayListMultimap.create();

public void addValue(Integer key, String value) {
    listMap.put(key, value);
}

public List<String> getValues(Integer key) {
    return listMap.get(key);
}

public Map<Integer, List<String>> asMap() {
    // See documentation for details
    return Multimaps.asMap(listMap);
}

Java 8 还提供了一种在单个语句中获取和初始化值的更方便的方法:

Map<Integer, List<String>> listMap = new HashMap<>();

public void addValue(Integer key, String value) {
    listMap.computeIfAbsent(key, k -> new ArrayList<>()).add(value);
}

附带说明一下,我会稍微修改一下您的原始示例,以避免在找到匹配键时进行额外查找:

public void addValue(Integer key, String value) {
    List<String> values = listMap.get(key);
    if (values == null) {
        listMap.put(key, values = new ArrayList<>());
    }
    values.add(value);
}

【讨论】:

  • 值得指出的是Map&lt;Integer, List&lt;String&gt;&gt; 能够存储ListMultimap&lt;Integer, String&gt; 不能存储的值:前者可以有一个与键相关联的空列表,同时仍然在@ 中报告该键987654328@;后者不能。看起来它不会影响 OP 的用例,但它有时是一个重要的区别。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-23
  • 2017-05-20
  • 2013-12-20
  • 2019-10-10
  • 2018-11-23
  • 1970-01-01
  • 2020-04-08
相关资源
最近更新 更多