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