Collectors.Characteristics.IDENTITY_FINISH Spec Clarification
Brian Goetz
brian.goetz at oracle.com
Mon Oct 15 15:14:00 UTC 2018
The intent is that the collector is free to either call the identity
function, or replace it with an unchecked cast instead, and client code
cannot tell the difference.
On 10/9/2018 10:48 AM, Chris Dennis wrote:
> I’m attempting to clarify the meaning/intent of the language in the specification of the identity-finish characteristic of collectors.
>
> The javadoc reads:
>
> Indicates that the finisher function is the identity function and
> can be elided. If set, it must be the case that an unchecked cast
> from A to R will succeed.
>
> In the following code the second sentence clearly indicates that the second cast from A to R must succeed. What I’m trying to confirm however is that the first sentence is intended to require that the finisher is a true identity function, so the result of the collector must be one of the instances created through the supplier, and that therefore the cast from R to A is also safe.
>
> public static void main(String[] args) {
> Stream<String> a = Stream.of("foo", "bar", "baz");
> Stream<String> b = Stream.of("alice", "bob", "eve");
>
> System.out.println(collect(Stream.of(a, b), partitioningBy(s -> s.startsWith("b"), toList())));
> }
>
> public static <T, A, R> R collect(Stream<Stream<T>> streams, Collector<T, A, R> collector) {
> if (collector.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
> return streams.map(s -> s.collect(collector))
> // Indicates that the finisher function is the identity function and can be elided.
> .map(r -> (A) r)
> .reduce(collector.combiner())
>
> // If set, it must be the case that an unchecked cast from A to R will succeed.
> .map(a -> (R) a)
> .orElse(Stream.<T>empty().collect(collector));
> } else {
> return streams.flatMap(identity()).collect(collector);
> }
> }
>
> Thoughts, opinions?
>
> Thanks,
>
> Chris Dennis
More information about the core-libs-dev
mailing list