为了账号安全,请及时绑定邮箱和手机立即绑定

Java 流对地图列表的值求和

Java 流对地图列表的值求和

当年话下 2021-09-15 15:20:09
我想确定“行”中的“列”或更好的:构建像 List> rows 这样的地图列表的总和是否有可能以某种方式对每个不同列的所有值求和?该函数应返回一个 Map,以列为键,所有值的总和为值。summMap.get("columname")假设我有以下地图列表:List<Map<String, Long>> mapList = new ArrayList();Map<String, Object> map1 = new HashMap<>();Map<String, Object> map2 = new HashMap<>();Map<String, Object> map3 = new HashMap<>();map1.put("col1", 90);map1.put("col2", 50);map1.put("col3", 10);map2.put("col1", 90);map2.put("col2", 50);map2.put("col3", 10);map3.put("col1", 90);map3.put("col2", 50);map3.put("col3", 10);mapList.add(map1);mapList.add(map2);mapList.add(map3);Map<String, Long> sum = mapList.stream().distinct().sum() // Example// result i'm awaiting/expectingLong sumVal1 = sum.get("col1"); // 270Long sumVal2 = sum.get("col2"); // 150Long sumVal3 = sum.get("col3"); // 30Long sumVal = sum.get("col1");
查看完整描述

3 回答

?
桃花长相依

TA贡献1860条经验 获得超8个赞

就这么简单

Map<String, Long> sum = mapList.stream()
    .flatMap(m -> m.entrySet().stream())
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Long::sum));


查看完整回答
反对 回复 2021-09-15
?
DIEA

TA贡献1820条经验 获得超2个赞

霍尔格已经提供了一个干净的解决方案,但我想,你也可以尝试flatMap,并groupingBy为:


Map<String, Long> sum = mapList.stream().flatMap(map -> map.entrySet().stream())

                .collect(groupingBy(Map.Entry::getKey, summingLong(Map.Entry::getValue)));

您问题的完整解决方案:


import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import static java.util.stream.Collectors.*;


public class ListMapSum {

    public static void main(String... args) {

        List<Map<String, Long>> mapList = new ArrayList();

        Map<String, Long> map1 = new HashMap<>();

        Map<String, Long> map2 = new HashMap<>();

        Map<String, Long> map3 = new HashMap<>();

        map1.put("col1", 90L);

        map1.put("col2", 50L);

        map1.put("col3", 10L);

        map2.put("col1", 90L);

        map2.put("col2", 50L);

        map2.put("col3", 10L);

        map3.put("col1", 90L);

        map3.put("col2", 50L);

        map3.put("col3", 10L);

        mapList.add(map1);

        mapList.add(map2);

        mapList.add(map3);

        Map<String, Long> sum = mapList.stream().flatMap(map -> map.entrySet().stream())

                .collect(groupingBy(Map.Entry::getKey, summingLong(Map.Entry::getValue)));

        Long sumVal1 = sum.get("col1"); // 270

        Long sumVal2 = sum.get("col2"); // 150

        Long sumVal3 = sum.get("col3"); // 30

    }

}


查看完整回答
反对 回复 2021-09-15
?
噜噜哒

TA贡献1784条经验 获得超7个赞

这不支持并行执行,但可以通过修改中的最后一个参数来实现reduce:


private static Map<String, Long> reduceLongs(List<Map<String, Long>> maps) {

    return maps.stream()

        .flatMap(map -> map.entrySet().stream())

        .reduce(new HashMap<>(), (map, e) -> {

            map.compute(e.getKey(), (k ,v) -> v == null ? e.getValue() : e.getValue() + v);

            return map;

        }, (m1, m2) -> { throw new UnsupportedOperationException(); });

}

并通过测试:


final List<Map<String, Long>> maps = new ArrayList<>();


Map<String, Long> map1 = new HashMap<>();

Map<String, Long> map2 = new HashMap<>();


map1.put("col1", 90L);

map1.put("col2", 50L);


map2.put("col1", 90L);

map2.put("col2", 50L);


map2.put("col3", 100L);


maps.add(map1);

maps.add(map2);


final Map<String, Long> sums = reduceLongs(maps);


assertEquals(180L, sums.get("col1").longValue());

assertEquals(100L, sums.get("col2").longValue());

assertEquals(100L, sums.get("col3").longValue());


查看完整回答
反对 回复 2021-09-15
  • 3 回答
  • 0 关注
  • 182 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信