I am creating a function that reads a .txt file and returns a tree maps as Tree
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);
}
}