Search code examples
javastreambufferedreadertreemap

Return a Tree Map using streams in Java 11


I am creating a function that reads a .txt file and returns a tree maps as Tree


Solution

  • You may do it like so,

    Path path = Paths.get("path/to/file", "fileName.txt");
    try (Stream<String> lines = Files.lines(path)) {
        Map<Integer, Long> wordLengthCount = lines.map(l -> l.split(" ")).flatMap(Arrays::stream)
            .filter(s -> !s.isEmpty())
            .collect(Collectors.groupingBy(w -> w.length(), TreeMap::new, Collectors.counting()));
    }
    

    Just pass in a mapFactory, a supplier providing a new empty Map into which the results will be inserted. You can merely use a constructor reference as shown here to get the work done. Also notice that this is an overload of the groupingBy function.

    As mentioned below in the comment, this can further be simplified using a method reference in place of lambda,

    Map<Integer, Long> wordLengthCount = lines.map(l -> l.split(" ")).flatMap(Arrays::stream)
            .filter(s -> !s.isEmpty())
            .collect(Collectors.groupingBy(String::length, TreeMap::new, Collectors.counting()));
    

    Coming back to your context, I would suggest you to pass in the file path to the method and it will return you the Map. So here's how it looks in practice.

    public static Map<Integer, Long> wordCountByLength(String path) {
        try (Stream<String> lines = Files.lines(Paths.get(path))) {
            return lines.map(l -> l.split(" ")).flatMap(Arrays::stream).filter(s -> !s.isEmpty())
                    .collect(Collectors.groupingBy(String::length, TreeMap::new, Collectors.counting()));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }