0

I as trying out some Spring reactive code and following is relevant piece of code

Supplier<Stream<Long>> longStreamSupplier = ()
            -> LongStream.iterate(0,
                    nextLong -> nextLong + 1).boxed();

Flux<Long> fooIds = Flux.fromStream(longStreamSupplier); 

Last line above gives compilation error in Intellj IDE saying there is not method which accepts the type.

However if i convert it to following :

Flux<Long> fooIds = Flux.fromStream(() -> LongStream
                    .iterate(0, nextLong -> nextLong + 1)
                    .boxed());

This works fine. Why it cant accept a reference variable pointing to the same lambda expression i am passing in second piece of code?

Shailesh Vaishampayan
  • 1,766
  • 5
  • 24
  • 52

2 Answers2

2

Your argument type for fromStream is wrong in the first example. In the second snippet it has been correctly deduced as Supplier<Stream<? extends Long>>, while in the first you explicitly "narrowed" it down to something that's not accepted by Flux.streamOf.

You could fix the first snippet by writing:

        Supplier<Stream<? extends Long>> longStreamSupplier = ()
                -> LongStream.iterate(0,
                nextLong -> nextLong + 1).boxed();

        Flux<Long> stream = Flux.fromStream(longStreamSupplier);

You might ask yourself

Why isn't there an overload for this function which accepts explicitly Supplier<Stream<T>> instead of Supplier<Stream<? extends T>>.

That's because of Java Type Erasure, consider the following two functions:


    private void foo(Supplier<Stream<? extends  Long>> stream) {

    }
    private void foo(Supplier<Stream<Long>> stream) {

    }

When compiling, after type erasure, we are left with:


    private void foo(Supplier stream) {

    }
    private void foo(Supplier stream) {

    }

Which produces a compile error, because we have two functions with identical definitions. So in the case of Flux::fromStream, the more flexible version is implemented.

adnan_e
  • 1,764
  • 2
  • 16
  • 25
1

That's because the longStreamSupplier variable has type Y<X<A>>, while the method expects an argument with type Y<X<? extends A>>, and these types aren't interchangeable.

edit

you can change the variable type to make the first example compile,

Supplier<Stream<? extends Long>> longStreamSupplier = ..
Daniele
  • 2,672
  • 1
  • 14
  • 20