当键与 Java Stream API 重复时如何添加 Map 的内部元素

How to add inner elements of Map when keys are duplicate with Java Stream API

我有一个 List<Map<String, Object>> 这样的列表

[
   {"A": 50,
      "B": 100,
      "C": 200,
      "D": "Auction"
    },
    {
      "A": 101322143.24,
      "B": 50243301.2,
      "C": 569,
      "D": "Sold Promissory Buyer"
    },
    {
      "A": 500,
      "B": 1000,
      "C": 1500,
      "D": "Auction"
    }]

我正在使用这个流 API 方法将这个列表转换成 Map

finalSalesReportForSoldProperty.stream().collect(Collectors.toMap(tags -> ((String) tags.get("D")).replaceAll("[\- ]", ""), Function.identity()));

但它抛出 java.lang.IllegalStateException: Duplicate key 异常,因为我的列表有重复的键

我想添加重复键的内部元素,我想要这样的输出

    "Auction": {
           "A": 550, 
           "B": 1100, 
           "C": 1650, 
           "D": "Auction" 
      } ,
"Sold Promissory Buyer" :{ 
          "A": 101322143.24,
          "B": 50243301.2,
          "C": 569,
          "D": "Sold Promissory Buyer"
        }

是否可以通过 Java 流 API?

您需要使用 toMap(keyMapper, valueMapper, mergeFunction) 收集器的 mergeFunction 参数。此函数在重复值上调用并将这两个值合并为一个新值。

在这种情况下,我们需要通过对具有相同键的值求和来合并两个映射。最简单的解决方案是遍历第二个映射的所有条目并合并第一个映射中的每个条目。如果映射不存在,将使用正确的值创建它。如果是,则新值将是两个当前值的总和。

现在,假设每个值实际上是 Double:

finalSalesReportForSoldProperty.stream().collect(Collectors.toMap(
    tags -> ((String) tags.get("assetStatus")).replaceAll("[\- ]", ""),
    Function.identity(),
    (m1, m2) -> {
        Map<String, Object> map = new HashMap<>(m1);
        m2.entrySet().stream()
                     .filter(e -> e.getValue() instanceof Double)
                     .forEach(e -> map.merge(e.getKey(), e.getValue(), (o1, o2) -> ((Double) o1) + ((Double) o2)));
        return map;
    }
));