如何在为不包含重复项的项指定特定逻辑的同时连接两个Java流?

Ant*_*ony 3 java collections java-8 java-stream

我有两个地图使用相同的对象作为键.我想按键合并这两个流.当两个地图中都存在一个键时,我希望生成的地图能够运行一个公式.当一个键存在于单个映射中时,我希望该值为0.

Map<MyKey, Integer> map1;
Map<MyKey, Integer> map2;

<Map<MyKey, Double> result =
    Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
        .collect(Collectors.toMap(
            Map.Entry::getKey, Map.Entry::getValue,
            (val1, val2) -> (val1 / (double)val2) * 12D));
Run Code Online (Sandbox Code Playgroud)

如果两个映射中都存在键,这将使用公式,但我需要一种简单的方法来设置仅存在于两个映射之一中的键的值为0D.

我可以通过设置数学并尝试计算两个keySet的内连接,然后从它们的完整外连接中减去内连接结果来做到这一点......但是这是很多不必要的工作.

有没有更好的方法,或者我可以使用Streaming API轻松做些什么?

And*_*eas 6

这是一种简单的方法,只流式传输键,然后查找值,并保持原始地图不变.

Map<String, Double> result =
    Stream.concat(map1.keySet().stream(), map2.keySet().stream())
          .distinct()
          .collect(Collectors.toMap(k -> k, k -> map1.containsKey(k) && map2.containsKey(k)
                                                 ? map1.get(k) * 12d / map2.get(k) : 0d));
Run Code Online (Sandbox Code Playgroud)

测试

Map<String, Integer> map1 = new HashMap<>();
Map<String, Integer> map2 = new HashMap<>();
map1.put("A", 1);
map1.put("B", 2);
map2.put("A", 3);
map2.put("C", 4);
// code above here
result.entrySet().forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

产量

A=4.0
B=0.0
C=0.0
Run Code Online (Sandbox Code Playgroud)

  • 与我的不同,你的答案适用于`Map <?,Integer>`:) (4认同)