Extending Collector to handle a post-transform

Brian Goetz brian.goetz at oracle.com
Tue Jun 11 12:02:57 PDT 2013

On 6/11/2013 1:44 PM, Tim Peierls wrote:
> On Tue, Jun 11, 2013 at 1:26 PM, Brian Goetz <brian.goetz at oracle.com
> <mailto:brian.goetz at oracle.com>> wrote:
>         Yes, it's not yet "all gain, no pain".  Where I am now, the
>         existence of an internal type still appears; Collector takes
>         type arguments <T, I, R> (input, intermediate, result), but all
>         the occurrences of Collector in the API specify ? as the second
>         parameter:
>          public static Collector<String, ?, String> toStringBuilder()
> That's not as bad as I feared, but given the importance of Collector to
> the whole Stream framework, I'm still worried about scaring people away
> with mysterious type parameters. Could Collector<T, R> extend
> BaseCollector<T, X, R>? Implementers of the latter care about X, clients
> of the former don't.

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.

For example, you could not do:

   interface BaseCollector<T,I,R> {
       Supplier<I> resultSupplier();
       BiFunction<I,T,I> accumulator();

   interface Collector<T,R> extends BaseCollector<T,?,R> { }

(compile-time error).

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.

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