Best way to create a stream of functions?

I want to make a lazy evaluation in a list of functions that I defined as follows:

Optional<Output> output = Stream.<Function<Input, Optional<Output>>> of( classA::eval, classB::eval, classC::eval) .map(f -> f.apply(input)) .filter(Optional::isPresent) .map(Optional::get) .findFirst(); 

where, as you can see, each class (a, b, and c) has a specific Optional<Output> eval(Input in) method. If I try to do

 Stream.of(...).... 

ignoring the explicit type, it gives

T is not a functional interface

collection error. Do not allow functional interface type for T generic type in .of(T... values)


Is there a faster way to create a stream of these functions? I don't like to explicitly define the of method with Function and its I / O types. Would this work in a more general way?

This question is related to the topic of the following question:
Lambda expression and general method

+5
source share
2 answers

You can break it into two lines:

 Stream<Function<Input, Optional<Output>>> stream = Stream .of(classA::eval, classB::eval, classC::eval); Optional<Output> out = stream.map(f -> f.apply(input)) .filter(Optional::isPresent) .map(Optional::get) .findFirst(); 

or use casting:

 Optional<Output> out = Stream.of( (<Function<Input, Optional<Output>>>)classA::eval, classB::eval, classC::eval) .map(f -> f.apply(input)) .filter(Optional::isPresent) .map(Optional::get) .findFirst(); 

but I don’t think you can avoid specifying the type of the Stream element - Function<Input, Optional<Output>> - somewhere, because otherwise the compiler cannot deduce it from the method links.

+4
source

There is a method that allows you to omit the type Function<Input, Optional<Output>> , but this is not necessarily an improvement.

 Optional<Output> o = Stream.concat(Stream.of(input).map(classA::eval), Stream.concat(Stream.of(input).map(classB::eval), Stream.of(input).map(classC::eval))) .filter(Optional::isPresent) .map(Optional::get) .findFirst(); 

and it does not scale.

It seems the best option is to wait for Java-9 where you can use

 Optional<Output> o = classA.eval(input) .or(() -> classB.eval(input)) .or(() -> classC.eval(input)); 
+2
source

Source: https://habr.com/ru/post/1274125/


All Articles