Extending Collector to handle a post-transform

Brian Goetz brian.goetz at oracle.com
Tue Jun 11 15:47:04 PDT 2013


You're going to need to be more detailed about what you mean by "bad". 
What options are you talking about?

Here's how it will be used:

   stream.collect(Collectors.toList())

See, no question marks.

Here's what Collect looks like:

     <R, I> R collect(Collector<? super T, I, R> collector);

Again, no question marks there either.  (Well, there is one, but we're 
already comfortable with that one -- or at least we'd better be.)  The 
only place they show up is in the return type of the canned collectors.

If you know what the type parameters mean, what Collector<T, ?, R> says 
is "A Collector that accepts input elements of type T, with some 
internal but uncommitted intermediate representation, and a final result 
type of R."  This really isn't so mysterious.  Theoretically we could 
commit to the internal type for toList:

   Collector<T, List<T>, List<T>> toList() {...}

but for some Collectors, it would be a bug to commit to the type.  For 
example, average could be a

   Collector<T, long[], Long>

but we'd be foolish to constrain ourselves to this intermediate 
representation when doing so does not benefit the user at all.  (The 
reason we don't have average now is that we can't write it at all 
without the post-transform.)




On 6/11/2013 6:34 PM, Joe Bowbeer wrote:
> This toList looks bad to me. What's in the javadoc is what the IDE
> presents (right?), and I'm not very optimistic about the ? options it
> suggests. I'll try everything first.
>
> On Jun 11, 2013 3:27 PM, "Brian Goetz" <brian.goetz at oracle.com
> <mailto:brian.goetz at oracle.com>> wrote:
>
>         OK, scratch that. Here's a different approach:
>
>
>         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();
>               }
>         }
>
>
>     Right, that's one of the forms of "move the ugly elsewhere."
>
>     But really, do you find this:
>
>          public static <T>
>          Collector<T, ?, List<T>> toList() { ... }
>
>     all that offensive?  If you found that in the javadoc, would it
>     really make you wonder what that ? was all about?  Because this is
>     really as bad as it gets.
>


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