----- Mail original -----
> De: "Daniel Fuchs" <daniel.fu...@oracle.com>
> À: "Remi Forax" <fo...@univ-mlv.fr>
> Cc: "Patrick Concannon" <patrick.concan...@oracle.com>, "core-libs-dev" 
> <core-libs-dev@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

Reply via email to