Re: RFR[8238286]: 'Add new flatMap stream operation that is more amenable to pushing’

forax at univ-mlv.fr forax at univ-mlv.fr
Fri Jun 26 14:38:02 UTC 2020


----- Mail original -----
> De: "Daniel Fuchs" <daniel.fuchs at oracle.com>
> À: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "Patrick Concannon" <patrick.concannon at oracle.com>, "core-libs-dev" <core-libs-dev at openjdk.java.net>
> Envoyé: Vendredi 26 Juin 2020 16:13:08
> Objet: Re: RFR[8238286]: 'Add new flatMap stream operation that is more amenable to pushing’

> Hi Rémi,
> 
> On 25/06/2020 23:12, Remi Forax wrote:
>>> if i have already have a BiConsumer<Consumer<Object>, Object>, i would like to
>>> be able to call Stream<String>.mapMulti() with that bi-consumer as argument.
>> and obviously, i got it wrong, Consumer<Object> is not a super-type of
>> Consumer<String>, it should be a BiConsumer<Consumer<?>, Object> or a
>> BiConsumer<? super Consumer<String>, Object>, etc.
>> 
> 
> Right - I had actually to code it to convince me that
> 
> <R> StreamTest<R> mapMulti(BiConsumer<? super Consumer<R>, ? super T>
> mapper)
> 
> (where R is String) would actually accept a
> BiConsumer<Consumer<?>, Object> or a
> BiConsumer<Consumer<?>, Object> or a BiConsumer<? super
> Consumer<String>, Object>
> 
> However, if you try to implement such BiConsumers, and try to
> implement their accept method to call consumer.accept(o); then
> they fail to compile. Specifically:
> 
>     static BiConsumer<Consumer<?>, Object> c1 =
>             new BiConsumer<Consumer<?>, Object>() {
>         @Override
>         public void accept(Consumer<?> consumer, Object o) {
>             consumer.accept(o);
>         }
>     };
> 
>     static BiConsumer<Consumer<? super String >, Object> c2 =
>             new BiConsumer<Consumer<? super String>, Object>() {
>         @Override
>         public void accept(Consumer<? super String> consumer, Object o) {
>             consumer.accept(o);
>         }
>     };
> 
> will not compile:
> 
> StreamTest.java:12: error: incompatible types: Object cannot be
> converted to CAP#1
>             consumer.accept(o);
>                             ^
>   where CAP#1 is a fresh type-variable:
>     CAP#1 extends Object from capture of ?
> /Users/danielfuchs/test/HttpRealTestAsync/src/StreamTest.java:20: error:
> incompatible types: Object cannot be converted to CAP#1
>             consumer.accept(o);
>                             ^
>   where CAP#1 is a fresh type-variable:
>     CAP#1 extends Object super: String from capture of ? super String
> 
> Which brings me back to my question: is there any value in having a
> BiConsumer that is accepted by mapMulti, where the signature of the
> BiConsumer doesn't allow it to act on its consumer argument without
> casting?

for your first example, the only valid value for Consumer<?> is null, so consumer.accept(null) should work.
for the second example, Consumer<? super String> accepts any subtypes of String, given that String is final, the only possible type is String, so consumer.accept(o.toString()) should work.

BTW, you may think that nobody will create voluntarily a BiConsumer<Consumer<? super String >, Object>, and that's true, usually you get this kind of types as result of method call inference,
e.g. you have a function g(f(Consumer<? super T>)) with T=String and g signature being something like <E> BiConsumer<E, Object> g(E element).

> 
> best regards,
> 
> -- daniel

regards,
Rémi


More information about the core-libs-dev mailing list