(JAVA) I need to convert this (actually using foreach) using to streams

Viewed 100

I need to convert this code using streams but I don't know how to do it.

        List<String> lines = Files2.linesFromFile(ruta);
        List<List<String>> res = new ArrayList<>();
        for (String line : lines) {
            List<String> aux = new ArrayList<>();
            for (String element : line.split(",")) {
                aux.add(element);
            }
            res.add(aux);
        }

If I show the content of res I got:

[[ejercicios, practica, propuesta], [cadena, recomendar, definir], [elemento, implementar, sol], [ala, map, public, static]]

The content of lines is:

[ejercicios,practica,propuesta, cadena,recomendar,definir, elemento,implementar,sol, ala,map,public,static]

And I need to get the same output using stream, can somebody help me? Thanks in advance.

2 Answers

Using @Hulk's suggestion for Pattern.splitAsStream, you can replace your whole for...loop with:

res = lines.stream().map(l -> Pattern.compile(",").splitAsStream(l).collect(Collectors.toList()))
            .collect(Collectors.toList());

res value is:

[[ejercicios, practica, propuesta], [cadena, recomendar, definir], [elemento, implementar, sol]]

If you want to "flatten" you List of Lists of Strings (List<List<String>> res) and make it just one List of Strings (List<String>)

you can use flatMap as:

List<String res = lines.stream().flatMap(l -> Pattern.compile(",").splitAsStream(l))
            .collect(Collectors.toList());

or even better as @user16320675 suggested:

res = lines.stream().flatMap(Pattern.compile(",")::splitAsStream)
            .collect(Collectors.toList());

this outputs:

[ejercicios, practica, propuesta, cadena, recomendar, definir, elemento, implementar, sol]

Use Stream::map to transform each line and Stream::collect to create a new list from the stream.

Replacement for your code would be:

List<List<String>> res = lines.stream()
  .map(line -> {
    List<String> aux = new ArrayList<>();
    for (String element : line.split(",")) {
      aux.add(element);
    }
    return aux;
  })
  .collect(Collectors.toList());

But we can simplify it by using Arrays::asList to create List<String> from String[] without writing the for loop.

List<List<String>> res = lines.stream()
  .map(line -> Arrays.asList(line.split(",")))
  .collect(Collectors.toList());
Related