【问题标题】:Using streams/collect to transform a Map使用流/收集来转换地图
【发布时间】:2017-06-17 21:18:51
【问题描述】:

我正在尝试将一个 Map 转换为另一个 Map,其中新键只是原始键 toString()。使用流 API 我这样做如下:

    mapMap.entrySet().stream().collect(Collectors.toMap(
            (Map.Entry entry) -> entry.getKey().toString(),
            (Map.Entry entry) -> entry.getValue()
    ));

问题是这不保留内部 Map 类型。如果原始地图恰好是 HashMap,我不介意返回 TreeMap,但反过来会出现问题,因为删除了元素的排序。我一直在玩弄上述代码的变体来完成这项工作,但我似乎并没有走得太远。现在,我已经写了没有流,如下:

    TreeMap<String, Integer> stringMap = new TreeMap<>();
    for (OriginalType t: originalMap.keySet()) {
        stringMap.put(t.toString(), originalMap.get(t));
    }

谁能让我在正确的方向上使用流来做到这一点? 谢谢

【问题讨论】:

  • 流没有类似into 的函数可以将结果转储到某个实现中吗?
  • 生成的TreeMap 将使用键字符串的字典顺序,而不管原始映射的顺序如何。这没有保留任何东西。

标签: java-8 java-stream


【解决方案1】:

Collectors.toMap 的重载允许您指定要返回的地图类型。

mapMap.entrySet().stream().collect(Collectors.toMap(
        (Map.Entry entry) -> entry.getKey().toString(),
        (Map.Entry entry) -> entry.getValue(),
        (val1, val2) -> { throw new RuntimeException("Not expecting duplicate keys"); },
        () -> new TreeMap<>()
));

(关于第三个参数的说明:它旨在作为一个函数,将具有相同键的两个值合并在一起。当我不希望这些事情发生时,我更愿意抛出异常。)

【讨论】:

  • 或使用方法参考TreeMap::new
  • 确实如此。我不这样做的唯一原因是减少提问者的歧义范围。
  • 我不确定第三个参数是否正确。
  • @JoeC 算了。我总是把collectors的merge函数和map的merge函数搞混了,我觉得这里反之亦然。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多