javaexceptionarraylistmapreducejava-stream

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


So, as of now, I am trying to read Strings into a Stream, and then eventually use the output. As of now, the only goal is simply to print it out without errors, but so far I am having no luck. Essentially, all I'm trying to do, is take a list of Strings and convert them into a map. I'm running into two different issues. One, my code triggers a Exception in thread "main" java.lang.UnsupportedOperationException on the line below containing current.get(item).addAll(update.get(item)); and two, I ultimately want to produce a Map that I can use once the stream is done processing. I thought that is what the reduce method was for, but I'm not sure how to use the Map I'm trying to produce here after the stream has closed. Suppose you have a text file string.txt that looks like:

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

Ideally the output would be a map of lists similar to this:

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

My code looks similar to the following:

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();
        }
    }  
}

I would really appreciate any help that you can provide! Thanks in advance!


Solution

  • Here is how the example would work.

    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);
    

    Prints

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