I wish to do lazy evaluation on a list of functions I've 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 see, each class (a, b & c) has an Optional<Output> eval(Input in)
method defined. If I try to do
Stream.of(...)....
ignoring explicit type, it gives
T is not a functional interface
compilation error. Not accepting functional interface type for T
generic type in .of(T... values)
Is there a snappier way of creating a stream of these functions? I hate to explicitly define of
method with Function
and its in-out types. Wouldn't it work in a more generic manner?
This issue stems from the topic of the following question;
Lambda Expression and generic method
答案 0 :(得分:4)
你可以把它分成两行:
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();
或使用演员:
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();
但我不认为您可以避免在某处指定Stream
元素的类型 - Function<Input, Optional<Output>>
,否则编译器无法从方法引用中推断它。
答案 1 :(得分:3)
有一种方法可以省略Function<Input, Optional<Output>>
类型,但它不一定是改进
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();
并且它不会缩放。
看来,最好的选择是等待Java-9,你可以使用
Optional<Output> o = classA.eval(input)
.or(() -> classB.eval(input))
.or(() -> classC.eval(input));