Refactor of Collector interface (original) (raw)
Brian Goetz brian.goetz at oracle.com
Fri Feb 8 08:39:46 PST 2013
- Previous message: Refactor of Collector interface
- Next message: Refactor of Collector interface
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hmm, it's difficult for me to perceive what these benefits are from looking at the change to Collectors.java <http://hg.openjdk.java.net/lambda/lambda/jdk/diff/221c5b4f706c/src/share/classes/java/util/stream/Collectors.java>, and the file did get 70 lines longer as a result of the change fwiw, and seems to rely more on private abstract base classes that other Collector implementors won't have.
It actually got smaller when this transform was applied, but more stuff went into Collectors in the same changeset, such as the mapped() combinators.
I have no objection to making that abstract base class public if that's a concern, though it's not really necessary since Collector writers can do without it:
class FooCollector implements Collector { Supplier resultSupplier() { return Foo:: new; } ... }
The abstract class is mostly there as a "fake tuple" class for convenience of the Collectors implementation, and I think we're on record as saying that it is reasonable to expect users to write their own fake tuple classes.
(How do you get to side-by-side diff in this thing? I feel quite blind without it and am thus stuck in "I don't get it" mode.)
On Fri, Feb 8, 2013 at 8:22 AM, Kevin Bourrillion <kevinb at google.com_ _<mailto:kevinb at google.com>> wrote: My subjective sense of good Java API design very strongly prefers the "before" picture here, which I see as a lot more "Java-like", so I'm taking a closer look. I assume that the trade-offs we're weighing here are purely to do with what it's like to be a Collector implementor, correct? On Fri, Feb 8, 2013 at 7:25 AM, Brian Goetz <brian.goetz at oracle.com_ _<mailto:brian.goetz at oracle.com>> wrote: 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); } to public interface Collector<T, R> { Supplier resultSupplier(); BiConsumer<R, T> accumulator(); BinaryOperator 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.
-- Kevin Bourrillion | Java Librarian | Google, Inc. |kevinb at google.com <mailto:kevinb at google.com> -- Kevin Bourrillion | Java Librarian | Google, Inc. |kevinb at google.com <mailto:kevinb at google.com>
- Previous message: Refactor of Collector interface
- Next message: Refactor of Collector interface
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the lambda-libs-spec-observers mailing list