Collector
Brian Goetz
brian.goetz at oracle.com
Tue Mar 12 19:34:41 PDT 2013
Yes, this is a very desirable feature. I spent a long time trying to
get this to work, but was not able to come up with an acceptable API
that gave the desired flexibility without making the API horribly
complicated or imposing unreasonable performance costs.
This shows up with averaging (intemediate state is int[2]), string
concat (StringBuilder), etc.
The basic problem is when the collector is the "downstream" of another
collector, such as grouping. Say, you want to do the query "average
sale by salesman". You'd like to reduce to int[2] and then convert to
double. But that means you either have to build a view map (keeping the
intermediate values around), or build a new map with the same keyset but
whose values are a function applied to the old keyset. Both are kind of
sucky, and the latter does not parallelize well.
The new experimental form for Collector may be more friendly to this
goal, though. And I'd like to have it -- its a definite "nice to have."
On 3/12/2013 10:26 PM, Howard Lovatt wrote:
> Hi,
>
> I have found the Collector interface and its primitive siblings really
> useful with streams. However I have wanted to add a feature where it works
> optionally with an intermediate type and then converts to the result type.
> IE
>
> interface Collector<T, I, R> {
> boolean isConcurrent();
>
> Supplier<I> intermediateSupplier();
>
> BiConsumer<I, T> accumulator();
>
> BinaryOperator<I> combiner();
>
> R resultConverter(I intermediateResult);
> }
>
> The reasons that I have wanted an intermediate type fall into
> two categories: for efficiency and/or for convenience of programming. For
> example it would be great to add a collector that made a
> string representation of a stream. EG assuming stream contains 1, 2, 3:
>
> stream.collect(toString)
>
> gives the string
>
> "[1, 2, 3]"
>
> Note the output is a String and it is surrounded by square brackets.
> Assuming that the intermediate type was a StringBuilder, the result
> converter function would be:
>
> String resultConverter(final StringBuilder intermediateResult) {
> intermediateResult.insert(0, '[');
> intermediateResult.append(']');
> return intermediateResult.toString();
> }
>
> The above example demonstrated both efficiency, StringBuilder is more
> efficient than String, and convenience, it is easier to add the '[]' at the
> end.
>
> Is this something others have wanted?
>
> -- Howard.
>
More information about the lambda-dev
mailing list