使用 Java 8 Stream API 减少 Map

Posted

技术标签:

【中文标题】使用 Java 8 Stream API 减少 Map【英文标题】:Reducing Map by using Java 8 Stream API 【发布时间】:2017-02-12 13:31:33 【问题描述】:

我有一张如下形式的地图:

Map<Integer, Map<String,Double>> START

令 INNER 为内部映射,即

Map<String,Double>

例如,我想在新的地图中减少 START 地图

Map<Integer, Double> END

它们具有相同的键,但具有不同的值。 特别是,对于每个键,我希望新的 Double 值是对应键的 INNER 映射中值的总和。

如何使用 JAVA 8 的 STREAM API 来实现这一点?

谢谢大家。

编辑:示例地图是

------------------------------
|      |  2016-10-02   3.45   |
| ID1  |  2016-10-03   1.23   |
|      |  2016-10-04   0.98   |
------------------------------
|      |  2016-10-02   1.00   |
| ID2  |  2016-10-03   2.00   |
|      |  2016-10-04   3.00   |
------------------------------

e 我想要一张像下面这样的新地图:

--------------------------------
|      |                       |
| ID1  |  SUM(3.45,1.23,0.98)  |
|      |                       |
--------------------------------
|      |                       |
| ID2  |  SUM(1.00,2.00,3.00)  |
|      |                       |
--------------------------------

【问题讨论】:

为什么你的内部地图的键是字符串?可以提供样图吗? 我想使用 STREAM API,因为我是新手,我需要更好地理解它。 你尝试了什么?向我们展示您的代码。 @talex 关于 Stream API,我还没有写任何代码。在旧代码中,我遍历哈希映射,逐键执行求和运算。现在,我的目标是通过使用 Stream 来达到相同的结果,而不是手动编写所有代码 @Fab 你为什么不自己试试呢?如果您使用别人为您编写的代码,您将永远学不会任何东西。 【参考方案1】:

它会为你工作

    Map<Integer, Double> collect = START.entrySet()
        .stream()
        .collect(
            Collectors.toMap(
                Map.Entry::getKey, 
                e -> e.getValue()
                      .values()
                      .stream()
                      .reduce(0d, (a, b) -> a + b)
                )
        );

【讨论】:

***.com/a/39851906/463758 另一个答案通过流式传输entrySet() 而不是keySet() 来保存一次查找。【参考方案2】:

这应该是一个很好的例子:

public class Main 

    public static void main(final String[] args) 
        final Map<Integer, Map<String, Double>> tmp = new HashMap<>();
        tmp.put(1, new HashMap<String, Double>() 
            put("1", 3.45);
            put("2", 1.23);
            put("3", 0.98);
        );
        tmp.put(2, new HashMap<String, Double>() 
            put("1", 1.00);
            put("2", 2.00);
            put("3", 3.00);
        );

        System.out.println(tmp.entrySet().stream()
                .collect(
                    toMap(Map.Entry::getKey, 
                    data -> 
                        data.getValue()
                            .values().stream()
                            .mapToDouble(Number::doubleValue).sum())));
    


输出将是1=5.66, 2=6.0,所有这些都是获取映射的条目集,获取它的流并收集到内部映射值的新映射总和。

【讨论】:

你的代码给了我以下错误:方法 toMap(Map.Entry::getKey, ( data) -> ) is undefined type Start

以上是关于使用 Java 8 Stream API 减少 Map的主要内容,如果未能解决你的问题,请参考以下文章

Java 8 Stream API实例

Java Stream按条件减少多个列表

学习Java 8 Stream Api - Stream 周边及其他

java 8 Stream 代码清单+API介绍

Java 8新特性stream API用法总结

Java 8 Stream API具体解释