Collectors inventory

Raab, Donald Donald.Raab at gs.com
Wed Mar 6 12:32:05 PST 2013


Some suggestions:

1. I would rename overloaded forms for map and mapping for primitive types to:
	a. map, mapInt, mapLong, mapDouble on Stream
	b. mapping, mappingInt, mappingLong, mappingDouble on Collector
2. Rename joinWith to toMap
3. Move toStatistics directly to IntStream, LongStream, DoubleStream instead of using stream.collect(toStatistics())

The primitive form renames will make it less confusing to the reader of the code as to what they are getting, especially if someone codes in a fluent style.  When the primitive streams came out in one of the binary releases, I was confused editing our kata exercises, because the code had moved from being a Stream to a DoubleStream, and the protocols for these are slightly different.

Being able to compose Collectors/reducers is an interesting idea.  I think being able to move some of this protocol to a builder approach may make it easier to discover and use rather than having a lot of overloaded static forms on Collectors.      

> -----Original Message-----
> From: lambda-libs-spec-experts-bounces at openjdk.java.net [mailto:lambda-
> libs-spec-experts-bounces at openjdk.java.net] On Behalf Of Brian Goetz
> Sent: Thursday, February 21, 2013 6:02 PM
> To: lambda-libs-spec-experts at openjdk.java.net
> Subject: Collectors inventory
> 
> As I promised a long time ago, here's an overview of what's in
> Collectors currently.
> 
> There are 12 basic forms:
>   - toCollection(ctor)
>   - toList()
>   - toSet()
>   - toStringBuilder()
>   - toStringJoiner(delimiter)
>   - to{Long,Double}Statistics
> 
>   - groupingBy(classifier, mapFactory, downstream collector)
>   - groupingReduce(classifier, mapFactory, mapper, reducer)
>   - mapping(mappingFn, downstream collector)
>   - joiningWith(mappingFunction, mergeFunction, mapFactory)
>   - partitioningBy(predicate, downstream collector)
>   - partitioningReduce(predicate, mapper, reducer)
> 
> The toXxx forms should be obvious.
> 
> Mapping has four versions, analogous to Stream.map:
>   - mapping(T -> U, Collector<U, R>)
>   - mapping(T -> int, Collector.OfInt<R>)
>   - mapping(T -> long, Collector.OfLong<R>)
>   - mapping(T -> double, Collector.OfDouble<R>)
> 
> GroupingBy has four forms:
>   - groupingBy(T->K) -- standard groupBy, values of resulting Map are
> Collection<T>
>   - Same, but with explicit constructors for map and for rows (so you
> can produce, say, a TreeMap<K, TreeSet<T>> and not just a
> Map<K,Collection<T>>)
>   - groupingBy(T->K, Collector<T,D>) -- multi-level groupBy, where
> downstream is another Collector
>   - Same, but with explicit ctor for map
> 
> GroupingReduce has four forms:
>   - groupingReduce(T->K, BinaryOperator<T>) // simple reduce
>   - groupingReduce(T->K, Function<T,U>, BinaryOperator<U>) // map-
> reduce
>   - above two with explicit map ctors
> 
> JoiningWith has four forms:
>   - joiningWith(T->U)
>   - same, but with explicit Map ctor
>   - same, but with merge function for handling duplicates
>   - same, with both explicit map ctor and merge function
> 
> PartitioningBy has three forms:
>   - partitioningBy(Predicate)
>   - Same, but with explicit constructor for Collection (so you can get
> a Map<Boolean, TreeSet<T>>)
>   - partitioningBy(Predicate, Collector) // multi-level
> 
> PartitioningReduce has two forms:
>   - predicate + reducer
>   - predicate + mapper + reducer
> 
> Impl note: in any category, all but one are one-liners that delegate to
> the general form.
> 
> Plus, all the Map-bearing ones have a concurrent and non-concurrent
> version.
> 



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