如果您使用的是 Java 流 API,您如何在调用 reduce 后打印出列表映射?

If you are using the Java Stream API, how do you print out a Map of Lists following after calling reduce?

所以,到目前为止,我正在尝试将字符串读入流,然后最终使用输出。到目前为止,唯一的目标就是将它打印出来而不会出错,但到目前为止我还没有运气。本质上,我想要做的就是获取一个字符串列表并将它们转换成一个映射。我 运行 陷入两个不同的问题。第一,我的代码在下面的包含 current.get(item).addAll(update.get(item)); 的行中触发了一个 Exception in thread "main" java.lang.UnsupportedOperationException,第二,我最终想生成一个 Map,在流处理完成后我可以使用它。我认为这就是 reduce 方法的用途,但我不确定在流关闭后如何使用我试图在此处生成的地图。假设您有一个如下所示的文本文件 string.txt

A,a,ab,abc
B,b,bc,bdc

理想情况下,输出将是类似于此的列表映射:

{"A"=["a","ab","abd"], "B"=["b","bc","bcd"]} 

我的代码类似于以下内容:

public class Foo {

    public static void main(String[] args) {
        String path = "path/to/strings.txt";
        try (Stream<String> stringStream = Files.lines(Paths.get(path))) {
            stream.limit(5).filter(e -> {
                return (e.split(",").length == 2);
            }).map(e -> {
                String[] elements = e.split(",");
                Map<String, List<String>> eMap = new HashMap<String,List<String>>();
                eMap.put(elements[0], Arrays.asList(elements[1]));
                return eMap;
            }).reduce(new HashMap<String,List<String>>(), (current, update) -> {
                for(String item : update.keySet()){
                    if(current.containsKey(item)){
                        // ERROR HERE:
                        current.get(item).addAll(update.get(item));
                    }else{
                        // ERROR HERE:
                        current.put(item, update.get(item));
                    }
                }
                return current;
            });

            // ERROR HERE:
            System.out.println(stringStream);
            // Result: java.util.stream.ReferencePipeline$Head@XXXXXXXXXX
            // Expected: {"A"=["a","ab","abd"], "B"=["b","bc","bcd"]} 

        } catch (IOException e) {
            e.printStackTrace();
        }
    }  
}

如果您能提供任何帮助,我将不胜感激!提前致谢!

示例如下。

  • 首先通过有限拆分将流映射到两个元素。
  • 第一个元素 arr[0] 是映射键。
  • 第二个字符串 arr[1] 是再次拆分
    、流式传输并转换为列表的值
String[] a = { "A,a,ab,abc", "B,b,bc,bdc" };
Map<String, List<String>> map = Arrays.stream(a)
        .map(str -> str.split(",", 2))
        .collect(Collectors.toMap(arr -> arr[0],
                arr -> Arrays.stream(arr[1].split(","))
                        .collect(Collectors.toList())));

map.entrySet().foreach(System.out::println);

版画

A=[a, ab, abc]
B=[b, bc, bdc]

这是一个支持重复键的解决方案:

String[] input = { "A,a,ab,abc", "B,b,bc,bdc", "A,a1,a2,a3" };

Map<String, List<String>> result = Arrays.stream(input)
            .map(e -> e.split(","))
            .filter(a -> a.length >= 2)
            .collect(Collectors.toMap(
                    a -> a[0],
                    a -> Arrays.asList(a).subList(1, a.length),
                    (a, b) -> Stream.concat(a.stream(), b.stream()).collect(Collectors.toList())));

System.out.println(result);

输出

{A=[a, ab, abc, a1, a2, a3], B=[b, bc, bdc]}