Home > database >  Collectors.summingInt() and Collectors.joining()
Collectors.summingInt() and Collectors.joining()

Time:01-10

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

CodePudding user response:

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.

CodePudding user response:

Eran's answer basically sums it up, I just wanted to add that in your specific case, a more idiomatic (& definitely more readable) way to achieve what you want would be:

String catNames = cats.stream().map(Cat::getName).collect(Collectors.joining());

This way each operation can be examined independently and so is easy to read & understand:

  1. Map a list of cats to a list of their names
  2. Join the list of cat names into a single string

Whereas in your 3rd example you're performing both of the operations inside of collect, which is less natural to read.

  •  Tags:  
  • Related