Search code examples
javajava-8java-streamfunctional-interface

Better way to create a stream of functions?


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


Solution

  • 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, since otherwise the compiler can't infer it from the method references.