Extending Collector to handle a post-transform

Tim Peierls tim at peierls.net
Tue Jun 11 13:05:26 PDT 2013

On Tue, Jun 11, 2013 at 3:02 PM, Brian Goetz <brian.goetz at oracle.com> wrote:

> I haven't been able to make this work nicely.  You can move the ugly
> somewhere else, but its not clear whether it is a win.
> You could do:
>   interface Collector<T,R> extends BaseCollector<T,Object,R> { }
> which is arguably uglier, and now we're getting into the "poor man's
> typedef antipattern", since the interface Collector does nothing except to
> obfuscate the type arguments of BaseCollector.

OK, scratch that. Here's a different approach:

Remember the shift from having Collector provide the factory, accumulator,
and combiner methods directly to its being a tuple of Supplier, BiFunction,
and BinaryOperator? That shift didn't affect library *users* at all; it
just made things different (easier?) for *implementers*. Maybe the right
thing is to take further advantage of the fact that library users don't
care what methods Collector has, they just care what the element and result
types are.

For example,

/** Passed to Stream methods by client code */
public interface Collector<T, R> {
    <X> Tuple<T, X, R> asTuple();

    /** Called on by Stream implementations to perform collection process */
    interface Tuple<T, X, R> {
        Supplier<X> resultSupplier();
        BiFunction<X, T, X> accumulator();
        BinaryOperator<X> combiner();
        Function<X, R> transformer();
        Set<Characteristics> characteristics();

(I don't really like the name Tuple, but I had to pick something to
illustrate the idea.)

Stream methods that take a Collector c call c.asTuple() to get the thing
that provides the result supplier, accumulator, combiner, etc.  Typical
Collector implementations could also extend Collector.Tuple, so that
asTuple would just return this.

There would still be a static Collectors method to build a Collector out of
Supplier, BiFunction, and BinaryOperator; and another method taking a
Supplier, BiFunction, BinaryOperator, and a transformer Function.

This pushes the ugly to a separate javadoc page, leaving the Collector<T,
R> interface for use in method signatures.


More information about the lambda-libs-spec-observers mailing list