Java 8流-合并地图集合

fbi*_*jec 2 java java-8 java-stream

可以说我有一个带有以下签名的方法:

Map<String, String> merge (String[][] ... maps)
Run Code Online (Sandbox Code Playgroud)

它使用(可变)数量的二维映射数组来表示映射,例如:

        String[][] m1 = new String[][] {
            {"k1", "a"},
            {"k2", "b"}
        };

        String[][] m2 = new String[][] {
            {"k1", "a"},
            {"k2", "b"},
            {"k3", "c"}   
        };

        String[][] m3 = new String[][] {
            {"k1", "x"},
            {"k2", "b"}
        };
Run Code Online (Sandbox Code Playgroud)

现在,我可以像这样从左到右合并任意两个地图:

 Map<String, String> m1 = Stream.of(map1).collect(Collectors.toMap(k -> k[0], v -> v[1]));
 Map<String, String> m2 = Stream.of(map2).collect(Collectors.toMap(k -> k[0], v -> Optional.ofNullable(v[1]).orElse("null")));
 m1.forEach((key, value) -> m2.merge(key, value, (v1, v2) -> v1));
Run Code Online (Sandbox Code Playgroud)

但是我该如何合并各种数组映射的杂散数,以便在m1, m2, m3按照上面的定义通过之后,结果是:

        String[][] m3 = new String[][] {
            {"k1", "x"},
            {"k2", "b"}
            {"k3", "c"}   
        };
Run Code Online (Sandbox Code Playgroud)

shm*_*sel 6

如果我能正确理解您的问题,这很简单。您只需flatMap所有条目并收集到地图,然后使用合并函数选择后面的值:

Map<String, String> merge (String[][] ... maps) {
    return Arrays.stream(maps)
            .flatMap(Arrays::stream)
            .collect(Collectors.toMap(a -> a[0], a -> a[1], (a, b) -> b));
}
Run Code Online (Sandbox Code Playgroud)

如果要将其转换回数组,可以执行

String[][] m3 = merge(maps)
        .entrySet()
        .stream()
        .map(e -> new String[] { e.getKey(), e.getValue() })
        .toArray(String[][]::new);
Run Code Online (Sandbox Code Playgroud)

  • @fbielejec而不是`Optional.ofNullable(v [1])。orElse(“ null”)`,您可以简单地使用`String.valueOf(v [1])`。甚至`v [1] == null?“ null”:v [1]`更简单… (2认同)