Collector / Collectors

Brian Goetz brian.goetz at oracle.com
Wed Jun 26 12:29:49 PDT 2013


Yeah, I was afraid of this.  When you actually try to *use* it, we hit 
the limits of type inference.  Will hit the drawing board.

On 6/26/2013 3:10 PM, Brian Goetz wrote:
> 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