Say I have this Stream:
list.stream()
.map(fn1) // part1
.map(fn2) //
.filter(fn3) //
.flatMap(fn4) // part 2
.map(fn5) //
.filter(fn6) //
.map(fn7) //
.collect(Collectors.toList())
How can I make it look like:
list.stream()
.map(fnPart1)
.map(fnPart2)
.collect(Collectors.toList())
Without manually unwinding the fnX parts and putting them together (for maintenance reasons, I want to keep them untouched, and express the fnPartX with them).
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.
Java 8 offers the possibility to create streams out of three primitive types: int, long and double. As Stream<T> is a generic interface, and there is no way to use primitives as a type parameter with generics, three new special interfaces were created: IntStream, LongStream, DoubleStream.
With Java 8, Collection interface has two methods to generate a Stream. stream() − Returns a sequential stream considering collection as its source. parallelStream() − Returns a parallel Stream considering collection as its source.
You could express and compose it with functions:
Function<Stream<T1>, Stream<T2>> fnPart1 =
s -> s.map(fn1)
.map(fn2)
.filter(fn3);
Function<Stream<T2>, Stream<T3>> fnPart2 =
s -> s.flatMap(fn4)
.map(fn5)
.filter(fn6)
.map(fn7);
fnPart1.andThen(fnPart2).apply(list.stream()).collect(Collectors.toList());
The input and output types of the functions have to match accordingly.
This can be the basis for a more complex composition construct such as:
public class Composer<T>{
private final T element;
private Composer(T element){
this.element = element;
}
public <T2> Composer<T2> andThen(Function<? super T, ? extends T2> f){
return new Composer<>(f.apply(element));
}
public T get(){
return element;
}
public static <T> Composer<T> of(T element){
return new Composer<T>(element);
}
}
This can be used like this:
Composer.of(list.stream())
.andThen(fnPart1)
.andThen(fnPart2)
.get()
.collect(Collectors.toList());
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