Collectors.collecting ?
Paul Sandoz
paul.sandoz at oracle.com
Fri Jun 21 05:55:31 PDT 2013
On Jun 21, 2013, at 10:45 AM, Remi Forax <forax at univ-mlv.fr> wrote:
> Maybe the question is stupid, but I fail to understand why in collector API
> we have a way to perform a reduction with no side effect but no way to do the same thing with side effect
> (in fact there is a way with the newly introduced methods 'of' but it's verbose and not symmetric).
>
> Currently we can write:
> Arrays.stream(args).parallel().collect(
> Collectors.groupingByConcurrent(arg -> arg,
> Collectors.reducing(0, arg -> 1, Integer::sum)));
>
> but neither
> Arrays.stream(args).parallel().collect(
> Collectors.groupingByConcurrent(arg -> arg,
> Collectors.collecting(new MutableInt(), (arg, value) -> value.increment())));
> nor
> Arrays.stream(args).parallel().collect(
> Collectors.groupingByConcurrent(arg -> arg,
> Collectors.collectingConcurrent(new LongAdder(), (arg, adder) -> adder.increment())));
>
I don't see how the former would work, it's not concurrent and cannot be used in a reduction calculation since there is no way to combine intermediate values.
The latter could work if the collector reports CONCURRENT and UNORDERED, although it still breaks the Collector contract e.g. if that collector is wrapped by something else.
For this case perhaps Collector.ofConcurrent might be ok:
collect(ofConcurrent(() -> new LongAdder(), (arg, adder) -> adder.increment(), (l, r) -> l.add(r.sum())));
The ofConcurrent collector would report CONCURRENT and UNORDERED. When used concurrently the combiner is never used, but when used non-concurrently in a reduction calculation it will still work.
Paul.
More information about the lambda-libs-spec-experts
mailing list