Given the following code:
List<String> list = Arrays.asList("a", "b", "c");
list.stream()
.map(s -> s + "-" + s) //"a-a", "b-b", "c-c"
.filter(s -> !s.equals("b-b")) //"a-a", "c-c"
.forEach(s -> System.out.println(s));
map
and filter
are intermediate operations and forEach
is a terminal operation. Only after the execution of the terminal operation we can have the result of the data transformation.
Is there any way to force the evaluation to be more eager and to have some kind of intermediate result - without breaking the stream operations chain? For example I want to have the list of "a-a", "b-b", "c-c" (which would be the result of the first intermediate operation).
Terminal operations are eagerly loaded. They don't produce end result. They produce end result.
Intermediate Operation- These operations are used to pipeline other methods and to transform into the other streams. They don't produce results because these operation does not invoke until the terminal operation gets executed. Below are the examples − sorted(Comparator<T>) peek(Consumer<T>)
Streams are lazy because intermediate operations are not evaluated until terminal operation is invoked. Each intermediate operation creates a new stream, stores the provided operation/function and return the new stream. The pipeline accumulates these newly created streams.
Stream. Intermediate operators do not execute until a terminal operation is invoked, i.e. they are not executed until a result of processing is actually needed. We will be discussing a few of the important and most frequently used: filter(predicate) Method.
You can use peek
:
List<String> allPairs = new ArrayList<>();
List<String> list = Arrays.asList("a", "b", "c");
list.stream()
.map(s -> s + "-" + s) //"a-a", "b-b", "c-c"
.peek(allPairs::add)
.filter(s -> !s.equals("b-b")) //"a-a", "c-c"
.forEach(s -> System.out.println(s));
This way the computation still won't start until the terminal operation, but you can "intercept" the stream content at any point and use it in any way you like.
Beware however if your terminal operation is short-circuiting (like findFirst
): this way not all the elements might be passed to peek
.
Well ... if I understand your question correctly, you have to apply a terminal operation, before filtering by the not equals "b-b"
predicate. Then, you should call .stream()
on the intermediate result and do the filtering:
List<String> list = Arrays.asList("a", "b", "c");
list.stream()
.map(s -> s + "-" + s) //"a-a", "b-b", "c-c"
.collect(Collectors.toList()) //intermediate result
.stream()
.filter(s -> !s.equals("b-b")) //"a-a", "c-c"
.forEach(s -> System.out.println(s));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With