Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I group lines of strings separated by empty lines using java stream

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.

like image 606
Mox Avatar asked Oct 12 '25 07:10

Mox


1 Answers

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.

like image 180
DCTID Avatar answered Oct 14 '25 20:10

DCTID