java - 使用 STREAM API 在两个 HashMap 之间执行操作

标签 java hashmap java-8 java-stream

我在表单中有两个 HashMap

Map<Integer, Map<String,Double>> MAP_1
Map<Integer, Map<String,Double>> MAP_2

让 INNER 成为内部映射,即

Map<String,Double>

对于每对对应的键,我想在两个内部映射之间执行一个操作(例如减法)。反过来,应该在内部映射的两个相应键之间执行此操作。 生成的 map 应该是

Map<Integer,List<Double> RESULT

示例 map 是

MAP_1
------------------------------
|      |  2016-10-02   10.0   |
| ID1  |  2016-10-03   20.0   |
|      |  2016-10-04   30.0   |
------------------------------
|      |  2016-10-02   1.00   | 
| ID2  |  2016-10-03   2.00   |
|      |  2016-10-04   3.00   |
------------------------------

MAP_2
------------------------------
|      |  2016-10-02   2.00   |
| ID1  |  2016-10-03   3.00   |
|      |                      |
------------------------------
|      |  2016-10-02   1.00   | 
| ID3  |  2016-10-03   2.00   |
|      |  2016-10-04   3.00   |
------------------------------

RESULT
---------------
|      |  8.00 |
| ID1  |  17.0 |
|      |       |
---------------

因此,对于外部 map ,只需考虑 ID1;反过来,该操作必须涉及内部(公共(public))键“2016-10-02”和“2016-10-03”。

这是我当前的代码

 Set<Integer> common_keys = new LinkedHashSet<Integer>(map1.keySet());
    common_keys.retainAll(map2.keySet());
    System.out.println("Common keys: "+common_keys.toString());

    map1.forEach((k,v) -> {

        Map<String,Double> submap_1 = new LinkedHashMap<String,Double>(v);
        Map<String,Double> submap_2 = new LinkedHashMap<String,Double>(map2.get(k));

        Set<String> commons = new LinkedHashSet<String>(submap_1.keySet());
        commons.retainAll(submap_2.keySet());

        System.out.println(k+" : common days: "+commons);


        List<Double> val1 = submap_1.keySet()
                .stream()
                .filter(c -> commons.contains(c))
                .map(c -> submap_1.get(c))
                .collect(Collectors.toList());

        List<Double> val2 = submap_2.keySet()
                .stream()
                .filter(c -> commons.contains(c))
                .map(c -> submap_2.get(c))
                .collect(Collectors.toList());

        List<Double> ABS = IntStream.range(0, val1.size())
                .mapToObj(i -> val1.get(i) - val2.get(i))
                .collect(Collectors.toList());

        diff_abs.put(k, ABS);
        });

是否有一种更简单、更智能的方法来做到这一点,即使用 JAVA 8' STREAM API?

提前致谢

最佳答案

创建 Set 是不必要的。将其替换为检查另一张 map 中相同键的 null。此外,创建 map 的副本是不必要的,因为 map 永远不会在该方法中被修改。

public static <T, U> Map<T, List<Double>> merge(Map<T, Map<U, Double>> m1, Map<T, Map<U, Double>> m2) {
    Map<T, List<Double>> result = new HashMap<>();
    m1.forEach((k, v) -> {
        Map<U, Double> v2 = m2.get(k);
        if (v2 != null) {
            // both outer maps contain the same key
            ArrayList<Double> list = new ArrayList<>();
            v.forEach((innerK, innerV) -> {
                Double d = v2.get(innerK);
                if (d != null) {
                    // matching key in both inner maps
                    list.add(innerV - d);
                }
            });
            // list.trimToSize();
            result.put(k, list);
        }
    });
    return result;
}

关于java - 使用 STREAM API 在两个 HashMap 之间执行操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39870529/

相关文章:

java - 表格中按钮的翻转效果?

java - 当从我的主类访问时,我的(正确的) HashMap 返回 null -(初学者)

java - 嵌入式 jetty 是否支持 java 8 紧凑配置文件?

java - 如何通过 hashMap 调用迭代器

Java函数式-反转ANY对象的ANY列表类型

java - CompletableFuture 的实例无法获得预期结果

java - 如何为布局的宽度和高度设置动画?

java - 如何获取最频繁的项目

java - 复制二进制文件会将换行符更改为窗口标准..? java

java - 接口(interface)中的方法不能应用于给定类型;带 HashMap