Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing/Reusing intermediate results on a java 8 stream

I have a List of A , To execute filtering I need to map A to B. But once the filtering logic is done I still need A for further operations, So My question is would it be at all possible to achieve this? One approach I can think of is storing both A and B into a third type, so I have both available, while processing the stream, but not sure that is elegant and wondering if here is a better way.Or am I trying to fit a square peg in a round hole by using streams.

List<A> a;
List<B> b = a.stream().map(i -> load(i)).filter(need A here in addition to b)
like image 273
Pradyot Avatar asked Mar 08 '18 20:03

Pradyot


2 Answers

Well you can always pass two things wrapped into a Pair, array, List for example:

a.stream().map(i -> List.of(load(i), i)) // List#of is java-9, replace with Pair or array
          .filter(x -> x[0]...)
          .filter(y -> /* y is List here */)
like image 128
Eugene Avatar answered Oct 17 '22 11:10

Eugene


There is no elegant solution here, but you could do filtering within mapping:

.map(a -> {
    B b = load(a);
    return filter(a, b) ? b : null;
})
.filter(Objects::nonNull)

You don't need to create wrappers around the stream elements. The load method will be executed only once in case it is an expensive operation.

null is the default invalid value, it should be replaced if null is allowed or it can be returned from load.

like image 1
Andrew Tobilko Avatar answered Oct 17 '22 11:10

Andrew Tobilko