Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java stream "forEach" but not consuming stream

Sometimes it would be handy do "something" (e.g. print) with every element in a stream in between steps of processing the stream, e.g. for debugging.

A simple example could look like this, unfortunately this does not work as forEach consumes the stream:

List<String> list = new ArrayList<>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");

List<String> filteredList = 
        list.stream()
        .filter(s -> s.startsWith("t"))
        .forEach(System.out::println)
        .collect(Collectors.toList());

How can this be achieved?

like image 430
Raphael Roth Avatar asked Feb 12 '16 14:02

Raphael Roth


People also ask

Does forEach close the stream?

Kotlin allows you to use forEach here because DirectoryStream is an Iterable , which defines the forEach , but this does not close this stream. As documented on DirectoryStream : A DirectoryStream is opened upon creation and is closed by invoking the close method.

Can we use forEach in streams Java?

Stream forEach() method in Java with examplesStream forEach(Consumer action) performs an action for each element of the stream. Stream forEach(Consumer action) is a terminal operation i.e, it may traverse the stream to produce a result or a side-effect.

Which is faster forEach or stream in Java?

parallel foreach() Works on multithreading concept: The only difference between stream(). forEach() and parallel foreach() is the multithreading feature given in the parallel forEach(). This is way faster that foreach() and stream. forEach().

Can we use collect after forEach?

The forEach is designed to be a terminal operation and yes - you can't do anything after you call it. The idiomatic way would be to apply a transformation first and then collect() everything to the desired data structure. The transformation can be performed using map which is designed for non-mutating operations.


1 Answers

You are looking for the peek operation:

This method exists mainly to support debugging, where you want to see the elements as they flow past a certain point in a pipeline

This method will execute the given action on all elements of the Stream pipeline as they are consumed. As such, it allows to take a peek of the elements.

List<String> filteredList = 
    list.stream()
        .filter(s -> s.startsWith("t"))
        .peek(System.out::println)
        .collect(Collectors.toList());
like image 107
Tunaki Avatar answered Oct 15 '22 00:10

Tunaki