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