Firstly, I'd suggest avoiding the use of raw types and instead, use List<String[]> as the receiver type.

List<String[]> numbers = reader.lines()
                               .map(s -> s.split(delimiter)) // substitute with your deilimeter
                               .collect(Collectors.toList());

You mentioned that you wanted a LinkedList implementation. you should almost always favour ArrayList which toList returns by default currently although it is not guaranteed to persist thus, you can specify the list implementation explcitly with toCollection:

List<String[]> numbers = reader.lines()
                               .map(s -> s.split(delimiter)) // substitute with your deilimeter
                               .collect(Collectors.toCollection(ArrayList::new));

and likewise for LinkedList:

List<String[]> numbers = reader.lines()
                               .map(s -> s.split(delimiter)) // substitute with your deilimeter
                               .collect(Collectors.toCollection(LinkedList::new));
Answer from Ousmane D. on Stack Overflow
🌐
Attacomsian
attacomsian.com › blog › java-string-with-separator-to-list
Convert a comma-separated string to a list in Java
October 29, 2022 - String fruits = "?, ?, ?, ?, ?, ?"; List<String> fruitsList = Arrays.asList(fruits.split("\\s*,\\s*")); Java Stream API can also be used to convert to comma-separated string into a list, as shown below:
Discussions

java - How to split a String into a Stream of Strings? - Stack Overflow
(Some aspects of his analysis could ... Android Java, or some future Oracle / OpenJDK version.) The relative performance is likely depend on the length of the string being split, the number of fields, and the complexity of the separator regex. In a real application, the relative performance may also depend what you do with the Stream object, what ... More on stackoverflow.com
🌐 stackoverflow.com
java - How to convert comma-separated String to List? - Stack Overflow
If you have a string like ", whatever, ... empty string member to the list, one at the beginning and another one at the end. 2022-11-11T19:29:39.653Z+00:00 ... If a List is the end-goal as the OP stated, then already accepted answer is still the shortest and the best. However I want to provide alternatives using Java 8 Streams, that will give you more benefit if it is part of a pipeline for further processing. By wrapping the result of the .split function (a ... More on stackoverflow.com
🌐 stackoverflow.com
regex - Split list of words using streams in Java - Stack Overflow
I am having this method that takes a number of lists, which contain lines of books. I am combing them to a stream to then iterate over them to split on all non-letter's \\P{L}. Is there a way to ... More on stackoverflow.com
🌐 stackoverflow.com
December 31, 2020
java - Split List<String[]> into List<List<String[]>> - Code Review Stack Exchange
We have a list of string arrays i.e. List (which we got from a csv) which follows the hierarchy: 0000 3000 5000 5000 5000 . . . 3900 3000 5000 5000 ... More on codereview.stackexchange.com
🌐 codereview.stackexchange.com
October 28, 2021
🌐
Baeldung
baeldung.com › home › java › java streams › string operations with java streams
String Operations with Java and Stream API | Baeldung
January 8, 2024 - Java 8 has introduced a new Stream API that lets us process data in a declarative manner. In this quick article, we would learn how to use the Stream API to split a comma-separated String into a list of Strings and how to join a String array into a comma-separated String.
Top answer
1 of 3
138

Arrays.stream/String.split

Since String.split returns an array String[], I always recommend Arrays.stream as the canonical idiom for streaming over an array.

String input = "dog,cat,bird";
Stream<String> stream = Arrays.stream(input.split( "," ));
stream.forEach(System.out::println);

Stream.of/String.split

Stream.of is a varargs method which just happens to accept an array, due to the fact that varargs methods are implemented via arrays and there were compatibility concerns when varargs were introduced to Java and existing methods retrofitted to accept variable arguments.

Stream<String> stream = Stream.of(input.split(","));     // works, but is non-idiomatic
Stream<String> stream = Stream.of("dog", "cat", "bird"); // intended use case

Pattern.splitAsStream

Pattern.compile(",").splitAsStream(string) has the advantage of streaming directly rather than creating an intermediate array. So for a large number of sub-strings, this can have a performance benefit. On the other hand, if the delimiter is trivial, i.e. a single literal character, the String.split implementation will go through a fast path instead of using the regex engine. So in this case, the answer is not trivial.

Stream<String> stream = Pattern.compile(",").splitAsStream(input);

If the streaming happens inside another stream, e.g. .flatMap(Pattern.compile(pattern) ::splitAsStream) there is the advantage that the pattern has to be analyzed only once, rather than for every string of the outer stream.

Stream<String> stream = Stream.of("a,b", "c,d,e", "f", "g,h,i,j")
    .flatMap(Pattern.compile(",")::splitAsStream);

This is a property of method references of the form expression::name, which will evaluate the expression and capture the result when creating the instance of the functional interface, as explained in What is the equivalent lambda expression for System.out::println and java.lang.NullPointerException is thrown using a method-reference but not a lambda expression

2 of 3
3

Robustness

I can see no difference in the robustness of the three approaches.

Readability

I am not aware of any credible scientific studies on code readability involving experienced Java programmers, so readability is a matter of opinion. Even then, you never know if someone giving their opinion is making an objective distinction between actual readability, what they have been taught about readability, and their own personal taste.

So I will leave it to you to make your own judgements on readability ... noting that you do consider this to be a high priority.

FWIW, the only people whose opinions on this matter are you and your team.

Performance

I think that the answer to that is to carefully benchmark the three alternatives. Holger provides an analysis based on his study of some versions of Java. But:

  1. He was not able to come to a definite conclusion on which was fastest.
  2. Strictly speaking, his analysis only applies to the versions of Java he looked at. (Some aspects of his analysis could be different on (say) Android Java, or some future Oracle / OpenJDK version.)
  3. The relative performance is likely depend on the length of the string being split, the number of fields, and the complexity of the separator regex.
  4. In a real application, the relative performance may also depend what you do with the Stream object, what garbage collector you have selected (since the different versions apparently generate different amounts of garbage), and other issues.

So if you (or anyone else) are really concerned with the performance, you should write a micro-benchmark and run it on your production platform(s). Then do some application specific benchmarking. And you should consider looking at solutions that don't involve streams.

🌐
Techie Delight
techiedelight.com › home › java › convert comma-separated string to list in java
Convert comma-separated String to List in Java | Techie Delight
July 7, 2026 - The idea is to split the string using the split() method, convert the array into the stream, and then collect all the input elements into a new list using the Collectors.toList() method.
🌐
Benchresources
benchresources.net › home › java › java 8 – how to split a string and collect to any collection ?
Java 8 - How to split a String and Collect to any Collection ? - BenchResources.Net
September 28, 2022 - Collect split-ted String to List using Stream’s collect() method passing Collectors.toList() as argument · Finally, iterate & print List to console using List.forEach() method ... package in.bench.resources.split.string; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class SplitStringAndCollectToListUsingJava8Stream { public static void main(String[] args) { // original string String fruits = "Grapes, Apple, Mango, Banana, Orange, Melons"; System.out.println("Original comma-separted String :- \n" + fruits); // split String based on comma List<Stri
Find elsewhere
🌐
How to do in Java
howtodoinjava.com › home › string › comma-separated string to list in java (split and streams)
Comma-Separated String to List in Java (split and Streams)
3 weeks ago - String tags = "java, spring, docker"; String[] array = tags.split("\\s*,\\s*"); // [java, spring, docker] List<String> fixedSize = Arrays.asList(array); // [java, spring, docker] List<String> readOnly = List.of(array); // [java, spring, docker] List<String> mutable = new ArrayList<>(Arrays.asList(array)); // [java, spring, docker] List<String> cleaned = Arrays.stream(tags.split(",")).map(String::strip).toList(); // [java, spring, docker]
🌐
Javaexercise
javaexercise.com › java › convert-comma-separated-string-to-list-in-java
Convert Comma Separated String To List In Java | String Split() Method - Javaexercise
July 1, 2022 - The split() method returns an array of String, we trim all the whitespace by using the String::trim and then Collectors.toList() method returns a list of String elements. See the code examples. import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; /* * Code ...
🌐
ZetCode
zetcode.com › java › splitstring
Java split string - splitting strings in Java
To remove the white spaces, we use trim. ... The regular expression splits the input string by a comma character, which might have any number of white spaces before or after the comma. We can split strings with Pattern in a functional way using streams. ... import java.util.List; import java.util.regex.Pattern; import java.util.stream.Collectors; void main() { String phoneNumber = "202-555-0154"; List<String> output = Pattern.compile("-") .splitAsStream(phoneNumber) .collect(Collectors.toList()); output.forEach(System.out::println); }
🌐
Mkyong
mkyong.com › home › java › how to split a string in java
How to split a string in Java | mkyong.com
February 9, 2022 - package com.mkyong.string.split; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class StringSplitJava8 { public static void main(String[] args) { String phone = "012-3456789"; List<String> output = Arrays.stream(phone.split("-")) .collect(Collectors.toList()); System.out.println(output); } }
🌐
Medium
medium.com › @AlexanderObregon › turning-a-string-into-a-list-of-words-in-java-c1e4bd85cad8
Turning a String into a List of Words in Java | Medium
July 28, 2025 - Streams are built for cases like filtering, mapping, and collecting, but they don’t replace loops entirely. If you need to exit early, track indexes, or work with more than one array at once, a standard loop gives you more room to move. Every time you break a sentence into words with split(), Java walks through the string, looks for matches, and cuts at the right spots.
Top answer
1 of 3
6

Motivations for improvement

I think "solving in 1 or 2 statements" is not a good target. Aiming for Java 8 features for the sake of using Java 8 features is also not a good target. A better target would be a combination of:

  • correct and reasonably robust
  • easy to understand
  • reasonably efficient

Here's a bit shorter and more efficient, but pretty bad solution:

private List<List<String[]>> splitIntoBlocks(List<String[]> rows) {
    List<List<String[]>> blocks = new ArrayList<>();

    int start = 0;
    for (int index = 0; index < rows.size(); index++) {
        String marker = rows.get(index)[0];
        if (marker.equals("3000")) {
            start = index;
        } else if (marker.equals("3900")) {
            int end = index + 1;
            blocks.add(rows.subList(start, end));
        }
    }

    return blocks;
}

This is bad (as bad as the original code), because it doesn't validate the input. It will only work correctly with input in the assumed format, which it doesn't verify, and it doesn't detect or signal when something is wrong, which could lead to nasty bugs.

Validating inputs

The posted code assumes the input follows a certain format. It should at least document the assumptions, and state if the caller can be trusted to enforce those assumptions.

As you mentioned, the input comes from CSV files. Since the expected format is not captured by the List<String[]> type, I would be very cautious. A verification is needed somewhere to avoid bugs or undefined behavior, for example the following checks come to mind:

  • There are the same number of START and END markers (you already did this one)
  • The START and END markers don't overlap
  • (optional?) There are no garbage records after an END and before the next START
  • The rows are not empty (avoid crashing due to index out of bounds exceptions)

When any of these assumptions fail, I would either raise a custom exception that the caller can handle, or else throw IllegalArgumentException to fail fast.

So in fact, instead of making the posted code shorter, I'm suggesting to actually make it longer, by adding more validation logic.

Making the code easier to understand

Another answer already mentioned to improve the variable names. (I suggest following Java conventions with camelCase names, so startIndices and endIndices.)

The values "3000" and "3900" are magic strings. It would be better to use private static final constants for such values, so that they stand out, and with a descriptive name.

Building the lists of startIndices and endIndices use the same logic, duplicated. It would be good to extract to a helper method.

When returning a container type, it's usually more practical to return an empty container instead of null.

2 of 3
4

Low hanging fruit

l1 and l2 are very opaque variable names. start_indices and end_indices would be much more descriptive.


        //get all position of 3000
        List<Integer> l1 = IntStream.range(0,rows.size())
                .filter(i->rows.get(i)[0].equals("3000"))
                .boxed()
                .collect(Collectors.toList());

This code takes int indices, boxes them into Integer indices, and collects them into a List<Integer>. This results in many small objects in memory.

We can avoid the boxing, by replacing .boxed().collect(Collectors.toList()) with .toArray() and changing the variable type to int[].

        // get positions of all "3000"'s
        int[] start_indices = IntStream.range(0,rows.size())
                .filter(i->rows.get(i)[0].equals("3000"))
                .toArray();

Apply similar change to the group end indices, and corresponding changes to the final res construction.

Single Pass

The above is still passing over the rows input 3 times; the first to collect the starting indices, the second to collect the ending indices, and the third time to assemble the result. Three passes means you cannot apply this grouping operation on an ephemeral stream; it requires a concrete collection that can be repeatedly iterated over.

Moreover, an IntStream is being used to generate indices into the rows list -- a hack -- which requires an ArrayList or similar \$O(1)\$-indexable collection to avoid quadratic time complexity.

It would be much better to perform a single pass over the stream of data, and collecting the required groups along the way:

private List<List<String[]>> splitIntoBlocks(List<String[]> rows) {
   return rows.stream().collect(Block.collector());
}

Well, the above clearly solves the "looking for someone to solve this in perhaps 1 or 2 statements" request, but clearly additional work is still required. The Block.collector() class is required, writing of which (to handle possible splitting & parallel stream handling) is a non-trivial exercise. See Collector.of(...)

🌐
GeeksforGeeks
geeksforgeeks.org › java › how-to-convert-a-comma-separated-string-into-an-arraylist-in-java
How to Convert a Comma-Separated String into an ArrayList in Java? - GeeksforGeeks
November 16, 2024 - .collect(Collectors.toCollection(ArrayList :: new)) - This will collect the stream of strings into a new ArrayList through the collector. All the collected elements should be stored in an ArrayList.
🌐
Baeldung
baeldung.com › home › java › java string › convert a comma separated string to a list in java
Convert a Comma Separated String to a List in Java
September 3, 2025 - The split method we used to split our string of integers (ranks) uses zero as the limit, and so it ignores the empty strings, whereas the split used on the countries string retains empty strings in the returned array. Now, we’ll implement the same conversions using the Java Stream API.
🌐
Medium
medium.com › @AlexanderObregon › javas-pattern-splitasstream-method-explained-99ca4b345ccd
Java's Pattern.splitAsStream() Method Explained
October 29, 2024 - The splitAsStream() method from the java.util.regex.Pattern class is a powerful feature introduced in Java 8. It allows for splitting strings into a stream based on a regular expression, making it a great tool for processing large text files ...
🌐
Coderanch
coderanch.com › t › 724831 › java › Splitting-string-flatMapping-creating-objects
Splitting string, flatMapping it and creating objects using Java streams? (Features new in Java 8 forum at Coderanch)
January 4, 2020 - From my JSP page, I'll get something like this: String uri = request.getQueryString(); I want to create two Ticket objects for two Seat objects. In uri string, chars 2 and 3 are primary keys for seats. The idea is to use Java streams to perform splitting and creating objects.