Refactor of Collector interface

Brian Goetz brian.goetz at
Fri Feb 8 07:25:05 PST 2013

FYI: In a recent refactoring, I changed:

public interface Collector<T, R> {
     R makeResult();
     void accumulate(R result, T value);
     R combine(R result, R other);


public interface Collector<T, R> {
     Supplier<R> resultSupplier();
     BiConsumer<R, T> accumulator();
     BinaryOperator<R> combiner();

Basically, this is a refactoring from typical interface to 
tuple-of-lambdas.  What I found was that there was a lot of adaptation 
going on, where something would start out as a lambda, we'd wrap it with 
a Collector whose method invoked the lambda, then take a method 
reference to that wrapping method and then later wrap that with another 
Collector, etc.  By keeping access to the functions directly, the 
Collectors code got simpler and less wrappy, since a lot of functions 
could just be passed right through without wrapping.  And a lot of 
stupid adapter classes went away.

While clearly we don't want all interfaces to evolve this way, this is 
one where *all* the many layers of manipulations are effectively 
function composition, and exposing the function-ness made that cleaner 
and more performant.  So while I don't feel completely super-great about 
it, I think its enough of a win to keep.

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