如何计算 Map<> 中每个列表的总和?

Posted

技术标签:

【中文标题】如何计算 Map<> 中每个列表的总和?【英文标题】:How to compute sum for each list in Map<>? 【发布时间】:2021-12-18 09:11:00 【问题描述】:

这是我的地图Map&lt;LocalDate,List&lt;Integer&gt;&gt; map = new LinkedHashMap&lt;&gt;();

问题 1: 如何计算 Map 中每个列表的总和

地图输出

2020-01-22 [0, 0, 7, 0, 0, 0, 0, 0, 3, 8, 0, 4,0]
2020-01-23 [0, 0, 7, 0, 0, 0, 0, 0, 3, 0, 0, 4,0] 
2020-01-24 [0, 0, 7, 0, 0, 0, 0, 0, 3, 0, 0, 5,0]
2020-01-25 [0, 0, 8, 0, 0, 0, 0, 0, 3, 0, 0, 4,0]
2020-01-26 [0, 0, 7, 0, 0, 0, 0, 0, 3, 0, 0, 8,0]
2020-01-27 [0, 0, 9, 0, 0, 0, 0, 0, 3, 0, 0, 4,0]

我的尝试

Map<LocalDate,List<Integer>> map = new LinkedHashMap<>();
 List<Integer> integerList =map
                .values()
                .stream()
                .map(l->
                    int sum = l
                            .stream()
                            .mapToInt(Integer::intValue)
                            .sum();
                    return sum;
                ).collect(Collectors.toList());

这里的代码我试过了,只能形成新的列表和 计算它。但我想同时显示日期和它的num总和

所需输出(计算并显示每个列表的总和)

2020-01-22 [22]
2020-01-23 [14] 
2020-01-24 [15]
2020-01-25 [14]
2020-01-26 [18]
2020-01-27 [16]

【问题讨论】:

当您的计算正确时,要获得所需的输出,您应该同时遍历键和值,进行数学运算并将值重新分配给当前键。 java流foreach在这种情况下是否适用于同时迭代key和value? 不完全是,而是迭代键,然后在每次迭代中调用 get 方法。 好的,所以迭代键,然后对于键的每次迭代,使用get 检索每个键的整数列表;获取列表时,将我上面的计算应用于列表的总和,对吗? 【参考方案1】:

你可以试试这个

Map<LocalDate,Integer> result = new LinkedHashMap<>();
map.forEach((key, value) -> 
 result.put(key,value.stream().mapToInt(Integer::intValue).sum());
);

【讨论】:

【参考方案2】:

toMap 是一个很好的候选人:

public static void main(String[] args) 
    Map<LocalDate,List<Integer>> map = new LinkedHashMap<>();

    map.put(LocalDate.of(2020,01,22), List.of(0, 0, 7, 0, 0, 0, 0, 0, 3, 8, 0, 4,0));
    map.put(LocalDate.of(2020,01,23), List.of(0, 0, 7, 0, 0, 0, 0, 0, 3, 0, 0, 4,0));
    map.put(LocalDate.of(2020,01,24), List.of(0, 0, 7, 0, 0, 0, 0, 0, 3, 0, 0, 5,0));
    map.put(LocalDate.of(2020,01,25), List.of(0, 0, 8, 0, 0, 0, 0, 0, 3, 0, 0, 4,0));
    map.put(LocalDate.of(2020,01,26), List.of(0, 0, 7, 0, 0, 0, 0, 0, 3, 0, 0, 8,0));
    map.put(LocalDate.of(2020,01,27), List.of(0, 0, 9, 0, 0, 0, 0, 0, 3, 0, 0, 4,0));

    var output = map.entrySet().stream()
                  .collect(toMap(Map.Entry::getKey,
                                 e -> e.getValue().stream().reduce(0, Integer::sum)));

    System.out.println(output);


其中一个重载的toMap 需要一个 keyMapper - 这里是原始地图中的键 和一个 valueMapper - 在这里,我们通过对列表中的数字求和来映射(获取)值。

上述代码的输出可能如下所示:

2020-01-27=16, 2020-01-26=18, 2020-01-25=15, 2020-01-24=15, 2020-01-23=14, 2020-01-22=22

您可以使用重载的toMap 来指示使用LinkedHashMap

var output = map.entrySet().stream()
               .collect(toMap(
                  Map.Entry::getKey, 
                  e -> e.getValue().stream().reduce(0, Integer::sum), 
                  // Conflict resolving function: If the same key is seen again, 
                  // use the latest value. 
                  (oldValue, newValue) -> newValue, 
                  LinkedHashMap::new));

System.out.println(output);

上述代码的输出是:

2020-01-22=22, 2020-01-23=14, 2020-01-24=15, 2020-01-25=15, 2020-01-26=18, 2020-01-27=16

【讨论】:

以上是关于如何计算 Map<> 中每个列表的总和?的主要内容,如果未能解决你的问题,请参考以下文章

如何获得我的组件来计算React中复选框值的总和?

计算具有相似类别的每个 td 的总和

599. 两个列表的最小索引总和C++

599. 两个列表的最小索引总和C++

LeetCode 599 两个列表的最小索引总和[map] HERODING的LeetCode之路

如何计算Scheme中数字的位数总和?