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
Create a stream from Collection The Java Collection framework provides two methods, stream() and parallelStream() , to create a sequential and parallel stream from any collection, respectively.
The Kafka Streams application consists of a single Java Class that creates a stream from the Kafka Topic.
Stream of Primitives. 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.
Stream.of (T…t) method can be used to create a stream with the specified t values, where t are the elements. This method returns a sequential Stream containing the t elements. Below is the implementation of the above approach:
The Stream API, introduced in Java 8, it is used to process collections of objects. Stream is a sequence of objects, that supports many different methods which can be pipe lined to produce the desired result.
Streamlining processes and workflows may take some time and is best completed in small steps that contribute to your organization’s improved efficiency goals. Businesses may streamline processes by reviewing the details of how they manage their individual challenges.
The builder () method is used when the desired type should be additionally specified in the right part of the statement, otherwise the build () method will create an instance of the Stream. The iterate () method returns an infinite sequential ordered Stream produced by iterative application of a function f to an initial element seed.
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.
There is a way that allows to omit the Function<Input, Optional<Output>>
type, but it’s 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 doesn’t 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));
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