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

非 Y 不嫁゛ 提交于 2019-12-05 02:43:18

问题


I have a List of List<Map<String, Object>> like this

[
   {"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"
    }]

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()));

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

Is it possible through Java stream API?


回答1:


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.

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;
    }
));


来源:https://stackoverflow.com/questions/35180143/how-to-add-inner-elements-of-map-when-keys-are-duplicate-with-java-stream-api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!