Collector / Collectors

Brian Goetz brian.goetz at oracle.com
Tue Jun 25 13:26:35 PDT 2013


Here's the review comments we got.  Most have already been dealt with. 
One additional suggestion for a new Collector (transforming) comes out 
of this.

 From Mike:
  - Need extra disclaimers on summingDouble/averagingDouble.  Done.

 From Sam:
  - Fix the examples where things have changed to Optional.  Done.  See [1]

 From Joe:
  - <code> tags leaking into output.  This turns out to be a Javadoc bug 
when you have a @link to a class that is not present.  Will not appear 
in final output.
  - Example section repeated between Collector and Collectors.  I think 
this is OK; users may land on either first, and I think these examples 
are important.  Sadly Javadoc has no normal form.
  - General spec nits (some addressed already, others will be addressed 
in final pass).

 From Remi:
  - I don't understand how to create a Collector instead of forEach in 
this case:
     ConcurrentHashMap<String, LongAdder> map
         = new ConcurrentHashMap<>();
     Arrays.stream(args).parallel()
           .forEach( arg -> map.computeIfAbsent(arg, k -> new 
LongAdder()).increment() );  See [2]


[1] After changing the example:

  *     Map<Department, Employee> highestPaidByDept
  *         = employees.stream()
  * 
.collect(Collectors.groupingBy(Employee::getDepartment,
  * 
Collectors.maxBy(Comparators.comparing(Employee::getSalary))));

to

  *     Map<Department, Optional<Employee>> highestPaidByDept
  *         = employees.stream()...

this suggests we might want a combinator to add a post-function to an 
existing Collector, such as:

   <T,A,R,U> Collector<T,A,U>
             transforming(Collector<T,A,R> collector,
                          Function<R,U> transformer)

that can be used in the downstream of a groupingBy to transform away the 
Optional at the end:

   groupingBy(Employee::getDepartment,
              transforming(maxBy(...), Optional::get))

THis way, the user can get a Map<Department, Employee> rather than a 
Map<Departhment, Optional<Employee>>.


[2] This can be done, but it involves boxing.

Collector<Long, LongAdder, LongAdder> c =
   Collectors.of(LongAdder::new,
                 (a, v) -> a.increment(),
                 (a, b) -> /* merge LongAdder tables by key */);

ConcurrentMap<String, LongAdder> map
    = stream.collect(groupingByConcurrent(Function.identity(), c));



On 6/25/2013 4:01 PM, Brian Goetz wrote:
> I've closed the survey.  You can see responses here:
>
> https://www.surveymonkey.com/sr.aspx?sm=fAIHxonslEapeh3et_2biuRHRGUer22Q8awZI1yaJrsT0_3d
>
>
> I'll be summarizing and responding to these soon.
>
> On 6/18/2013 11:58 AM, Brian Goetz wrote:
>> I think I may (finally!) have a final API candidate for Collector /
>> Collectors.  Updated docs here:
>>
>>    http://cr.openjdk.java.net/~briangoetz/doctmp/doc/
>>
>> Salient recent changes:
>>   - Incorporation of finishing function into Collector
>>   - Renamings in Collector API
>>   - Morph toStringBuilder, toStringJoiner into joining()
>>   - Add prefix/suffix version of joining()
>>   - Addition of summingBy{Int,Long,Double}
>>   - Addition of averagingBy{Int,Long,Double}
>>   - Rename toXxxSummaryStatistics to summarizingXxx
>>   - no-see reducing, and minBy/maxBy collectors return Optional
>>   - elimination of canned merger functions from API
>>
>> Please review the API and spec.  I have set up a SurveyMonkey with the
>> usual password to collect review comments at:
>>
>>    https://www.surveymonkey.com/s/3TTBJ7K
>>
>>



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