when learning Flux (reactive-core) in java
, I meet following questions about Function.
This is Flux.zip()
method signature:
public static <I, O> Flux<O> zip(
final Function<? super Object[], ? extends O> combinator,
Publisher<?extends I>... sources) {
return zip(combinator, Queues.XS_BUFFER_SIZE, sources);
}
And when I try to invoke this method:
Flux<User> userFluxFromStringFlux(Flux<String> usernameFlux, Flux<String> firstnameFlux, Flux<String> lastnameFlux) {
// predefined function taking object[] and returns User
Function<Object[], User> function = array -> new User(array[0].toString(),array[1].toString(), array[2].toString());
// it is working without error
Flux.zip(function, usernameFlux, firstnameFlux, lastnameFlux);
// this is also working without error
Flux.zip(array -> {
return new User(array[0].toString(),array[1].toString(), array[2].toString());
}, usernameFlux, firstnameFlux, lastnameFlux);
// but this has error with array[0] "Array type expected; found: 'org.reactivestreams.subscriber<capture<? super java.lang.object>>'"
Flux.zip(array -> new User(array[0].toString(),array[1].toString(), array[2].toString()), usernameFlux, firstnameFlux, lastnameFlux);
return null;
}
The third way which using anonymous function, but IDEA reports that there is a error :
Array type expected; found: 'org.reactivestreams.subscriber>.
I wonder why predefined Function and anonymous function with explict return is working but anonymous function?
I appreciate your help.
Not a compiler expert, but I think it has to do with the java compiler seeing an ambiguity with the short form lambda: is what you are passing an inline Publisher
(since it is a functional interface) or a Function
?
This confusion is made possible because the short form doesn't have an explicit return
statement: in the case of the Publisher
option it would mean you create a User
to immediately be garbaged collected, but that's not the sort of things the compiler will forbid you to do.
So the target type of the lambda is assumed to be Publisher
, and thus array
is inferred to be a Subscriber
. But then the array index operator is used on it, which surely must be wrong.
On the other hand, putting in the brackets { }
removes that ambiguity by having an explicit return
type that seem to be used in the inference. To the compiler you can no longer be representing a Publisher
, so the next candidate (Function
) is used.
Another way of removing the ambiguity is to show the compiler that the array
is... an array:
Flux.zip((Object[] array) -> new User(array[0].toString(),array[1].toString(), array[2].toString())
, usernameFlux, firstnameFlux, lastnameFlux);