Collector / Collectors

Brian Goetz brian.goetz at oracle.com
Wed Jun 26 12:10:59 PDT 2013


Proposed spec.  (I like how simple the second path is, where all it does 
is replace finisher() with finisher().andThen(finisher)).

     /**
      * Returns a {@code Collector} that shares the accumulation 
behavior of this
      * one, but performs an additional finishing step.
      *
      * @apiNote
      * For example, the {@code Collector} returned by {@code 
Collectors.toList()}
      * produces a {@code List} that may be mutable.  To add 
immutability to this
      * {@code Collector}, you would do:
      *
      * <pre>{@code
      * Collector<T, ?, List<T>> c = Collector.toList()
      * 
.andThen(Collections::unmodifiableList);
      * }</pre>
      *
      * @param finisher The additional finishing step
      * @param <U> The type of the result of the finishing step
      * @return a {@code Collector} that shares the accumulation 
behavior of this
      * one, but performs an additional finishing step
      */
     default<U> Collector<T, A, U> andThen(Function<? super R, ? extends 
U> finisher) {
         Set<Characteristics> characteristics = characteristics();
         if (characteristics.contains(Characteristics.IDENTITY_FINISH)) {
             Set<Characteristics> cs;
             if (characteristics.size() == 1)
                 cs = EnumSet.noneOf(Characteristics.class);
             else {
                 cs = EnumSet.copyOf(characteristics);
                 cs.remove(Characteristics.IDENTITY_FINISH);
                 cs = Collections.unmodifiableSet(cs);
             }
             @SuppressWarnings("unchecked")
             Function<A, U> castFinisher = (Function<A, U>) finisher;
             return new Collectors.CollectorImpl<>(supplier(), 
accumulator(),
                                                   combiner(), castFinisher,
                                                   cs);
         }
         else {
             return new Collectors.CollectorImpl<>(supplier(), 
accumulator(),
                                                   combiner(),
 
finisher().andThen(finisher),
                                                   characteristics);
         }
     }



On 6/26/2013 2:51 PM, Tim Peierls wrote:
> On Wed, Jun 26, 2013 at 2:43 PM, Brian Goetz <brian.goetz at oracle.com
> <mailto:brian.goetz at oracle.com>> wrote:
>
>         Something like this?
>
>         interface Collector<T, A, R> {
>               /** Returns new collector like this one, but with finisher
>         composed
>         with this collector's finisher. */
>               <R2> Collector<T, A, R2> andThen(Function<? super R, ?
>         extends R2>
>         finisher);
>         }
>
>         with default implementation doing the obvious composition?
>
>
>     Yes, something almost exactly like that.
>
>
> This would remove the need for Collectors.of() to take a finisher argument.
>
> --tim


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