I have a Cat class, which has String name and int tailLength fields and String getName() and int getTailLength() methods. Cat instances are placed in List<Cat> cats. My question:
Why does this work fine:
int tailsEndToEnd = cats.stream().collect(Collectors.summingInt(Cat::getTailLength); //(1)
and this does not:
String allNames = cats.stream().collect(Collectors.joining(Cat::getName); //(2)
I know that I can collect the cats’ names like this:
cats.stream().collect(Collectors.mapping(Cat::getName, joining(", ")); //(3),
just curious as to why (2) does not work, seen that it is perfectly analogous to (1), regardless of how the output would look (no comma, etc).
Thanks
>Solution :
All Collector.joining variants return a Collector<CharSequence, ?, String>, which means they can only operate on a Stream<CharSequence>.
When you use Collectors.mapping(Cat::getName,joining(", "));, mapping transforms your Stream<Cat> to a Stream<CharSequence>, which allows that Streamto be processed byjoining()`.
You can’t directly process the Stream<Cat> with joining, since it has no variant that accepts a mapping function to convert your Cats to Strings.
All the arguments of joining are CharSequences, and serve as either delimiter, prefix or suffix.
This is unlike summingInt, which accepts a ToIntFunction<? super T> mapper function to map the elements of your Stream to an int.