I have the following input and I would like them to be grouped using the empty line as the logical divider.
input datatype:
List<String>
line1
line2
line3
line4
line5
line6
line7
line8
expected output: type: List<List>
{{line1, line2, line3}, {line4, line5, line6}, {line7, line8}}
While this is trivial using imperative programming, I am looking for a solution that uses functional programming in Java.
You don't say what Java version you are using, but this should work in Java8+. The reduce
function on stream
can give you what you want if you use the one with 3 args an initial value in this case a list with lists of string, a lambda function that takes the current result and a single string. This really does all the work of adding a new list when it sees a blank line. Finally, a combiner that explains how to combine 2 lists but is really just to help the compiler understand what is going on. In this case it does nothing but that so it can always return an empty list.
String input = "line1\n" +
"line2\n" +
"line3\n" +
"\n" +
"line4\n" +
"line5\n" +
"line6\n" +
"\n" +
"line7\n" +
"line8";
List<String> strings = Arrays.stream(input.split("\n")).collect(Collectors.toList());
List<List<String>> initial = new ArrayList<>();
initial.add(new ArrayList<>());
List<List<String>> result = strings.stream().reduce(initial, (subtotal, element) -> {
if (element.trim().isEmpty()) {
subtotal.add(new ArrayList<>());
} else {
subtotal.get(subtotal.size() - 1).add(element);
}
return subtotal;
}, (list1, list2) -> emptyList());
I get the output of a List<List<String>>
of result[[line1, line2, line3], [line4, line5, line6], [line7, line8]] which I believe is what you are after.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With