如果使用Java Stream API,如何在调用reduce之后打印出列表列表?

问题描述 投票:-1回答:2

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

非常感谢您能提供的任何帮助!预先感谢!

java exception arraylist stream mapreduce
2个回答
1
投票

这里是示例的工作方式。

  • 首先通过有限分割将流映射到两个数组。
  • [第一个元素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]

0
投票

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

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]}
© www.soinside.com 2019 - 2024. All rights reserved.