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