----- 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