Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to split a stream of Strings and generate a List of String-arrays?

I am fairly new to streams, so please help me out (and be gentle).

What I would like to do is the following. I have a BufferedReader that reads from a file in which each line looks something like this: "a, b". For example:

Example Input file

"a, b"

"d, e"

"f, g"

I would like to convert this to a LinkedList<String[]>:

Example LinkedList<String[]>

[{"a", "b"}, {"c", "d"}, {"f", "g"}]

How would you do this using a stream approach?

This is what I tried:

List numbers = reader.lines().map(s -> s.split("[\\W]")).collect(Collectors.toList());

This does not work. My IDE provides the following feedback:

Incompatible types. Required List but 'collect' was inferred to R: no instance(s) of type variable(s) T exist so that List<T> conforms to List

It shows... I am still trying to figure streams out.

like image 952
MWB Avatar asked Jan 03 '19 15:01

MWB


People also ask

Can we convert stream to list in Java?

Using Collectors. Get the Stream to be converted. Collect the stream as List using collect() and Collectors. toList() methods. Convert this List into an ArrayList.

Can you split a string array?

The split() method splits a string into an array of substrings. The split() method returns the new array. The split() method does not change the original string. If (" ") is used as separator, the string is split between words.


2 Answers

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));
like image 165
Ousmane D. Avatar answered Oct 05 '22 18:10

Ousmane D.


You may do it like so,

Path path = Paths.get("src/main/resources", "data.txt");
try (Stream<String> lines = Files.lines(path)) {
    List<String> strings = lines.flatMap(l -> Arrays.stream(l.split(","))).map(String::trim)
        .collect(Collectors.toCollection(LinkedList::new));
}

Read each line of the file, then split it using the delimiter. After that trim it to eliminate any remaining white space characters. Finally collect it to a result container.

like image 34
Ravindra Ranwala Avatar answered Oct 05 '22 20:10

Ravindra Ranwala