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