如何在使用Java Stream API复制密钥时添加Map的内部元素 [英] How to add inner elements of Map when keys are duplicate with Java Stream API

查看:306
本文介绍了如何在使用Java Stream API复制密钥时添加Map的内部元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有列表< 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

I am using this stream API method to convert this list into Map

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

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

But it throws me java.lang.IllegalStateException: Duplicate key exception, because my list has duplicate keys

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

I want to add the inner elements of duplicate key, I want my output like this

    "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?

Is it possible through Java stream API?

推荐答案

你需要使用 mergeFunction 参数的.html#toMap-java.util.function.Function-java.util.function.Function-java.util.functi on.BinaryOperator-rel =nofollow> toMap(keyMapper,valueMapper,mergeFunction) collector。此函数在重复值上调用,并将这两个值合并为一个新值。

You need to use the mergeFunction parameter of the toMap(keyMapper, valueMapper, mergeFunction) collector. This function is called on duplicate values and will merge those two values into a new one.

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

In this case, we need to merge two maps by summing the values with the same key. The easiest solution to do that is to iterate over all the entries of the second map and merge each entry in the first map. If the mapping does not exist, it will be created with the correct value. If it does, the new value will be the sum of the two current values.

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

Now, assuming each value is in fact a 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;
    }
));

这篇关于如何在使用Java Stream API复制密钥时添加Map的内部元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆