Seing a Collector as a Gatherer

forax at univ-mlv.fr forax at univ-mlv.fr
Wed Jan 17 20:16:41 UTC 2024


> From: "Viktor Klang" <viktor.klang at oracle.com>
> To: "Remi Forax" <forax at univ-mlv.fr>
> Sent: Wednesday, January 17, 2024 6:01:38 PM
> Subject: Re: Seing a Collector as a Gatherer

> Hi Rémi,

> Yes, this was something I was hoping to get into the preview, but I wasn't sure
> where that conversion should end up.

> There are a few different places where it might go:

> Gatherer.of(Collector)
> Gatherers.collect(Collector)
> Collector.asGatherer()
> Collectors.gather(Collector)

> I wasn't really convinced where it should go, and I was hesitant to making any
> changes to existing public interfaces as a "nice to have", so I opted to leave
> it out for now.

> I think people would prefer to see it on Collector as a default method, but as I
> said before, making changes to Collector wasn't something I was ready to
> prioritize for the (first) JEP.

I think this method is also important pedagogically, there should be a place that describe the relationship between a Collector and a Gatherer. 

For Gatherer.of(), this one seems alien compared to the other overloads of of()/ofSequential() and to a lesser extend I do not like too much to have overloads with one parameter with two different interfaces, because someone can comes with a class that implements both Collector and Integrator (as stupid as it is), 

For Gatherers.collect(Collector) is fine, 

For Collector.asGatherer(), a default method has the disadvantage that usually a Collector is typed from left to right so calling an instance method requires an intermediary variable 
Collector<String, ?, List<String>> collector = Collector.toList(); // ok 
Gatherer<String, ?, List<String>> gatherer = Collector.toList().asGatherer(); // we are in trouble here 
that's why Collectors.collectingAndThen() (aka compose the finisher) is a static method in Collectors and not an instance method in Collector (finishAndThen ?), 

For Collectors.gather(), methods inside Collectors tend to return a Collector. 

> Cheers,
>
regards, 
Rémi 

> Viktor Klang
> Software Architect, Java Platform Group
> Oracle

> From: core-libs-dev <core-libs-dev-retn at openjdk.org> on behalf of Remi Forax
> <forax at univ-mlv.fr>
> Sent: Wednesday, 17 January 2024 17:08
> To: core-libs-dev <core-libs-dev at openjdk.java.net>
> Subject: Seing a Collector as a Gatherer
> Hello,
> I may have overlook that, but it seems there is no method to see a Collector as
> a Gatherer.

> A Gatherer is more general than a Collector and a Gatherer with a greedy
> integrator that does not call Downstream.push in the intergator and only once
> is the finisher is basicaly a Collector.

> In code:
> <E, A, T> Gatherer<E, A, T> asGatherer(Collector<? super E, A, ? extends T>
> collector) {
> var supplier = collector.supplier();
> var accumulator = collector.accumulator();
> var combiner = collector.combiner();
> var finisher = collector.finisher();
> return Gatherer.of(supplier,
> Gatherer.Integrator.ofGreedy((state, element, _) -> {
> accumulator.accept(state, element);
> return true;
> }),
> combiner,
> (state, downstream) -> downstream.push(finisher.apply(state)));
> }

> This is eaxctly how Gatherer.fold() works.

> Is there a reason why such method does not exist ?

> regards,
> Rémi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20240117/e155a8ed/attachment.htm>


More information about the core-libs-dev mailing list