Reputation: 5702
I've written this code that doesn't compile:
String[] text = {"hello", "bye"};
IntStream.of(Arrays.stream(text).map(String::length)).sum()
Do I need to convert the stream to an IntStream? And why do I get an error when I pass String::length
to the map()
function?
Upvotes: 8
Views: 6821
Reputation: 17289
Try this
Arrays.stream(text)
.filter(Objects::nonNull)
.mapToInt(String::length)
.reduce(0,Integer::sum);
Upvotes: 3
Reputation: 34460
You should use Stream.mapToInt
in order to get an IntStream
instance:
String[] text = {"hello", "bye"};
int total = Arrays.stream(text).mapToInt(String::length).sum();
Upvotes: 14
Reputation: 56423
Do I need to convert the stream to an IntStream?
Well, you don't need to in order to find the total length of all the strings but it's better to do so for performance reasons.
And why do I get an error when I pass String::length to the map() function?
If you change the method reference to a lambda, you'll get a better hint at what is wrong. i.e.
IntStream.of(Arrays.stream(text).map(e -> e.length())).sum();
Now, you don't only have a squiggly line near the map
function but also under the IntStream.of
method. After hovering over the of
method on an IDE, I get the message:
"cannot resolve method of(java.util.stream.Stream<R>)"
Now, this tells us that we're passing the wrong thing to the of
method. There are two overloads of the of
method:
of(int... values)
of(int t)
As you can see these two methods expect either a set of values to be passed or a single value to be passed, being of type int
.
Clearly, the IntStream.of
method is not our friend, in this case, rather we will want:
int length = Arrays.stream(text) // Stream<String>
.mapToInt(String::length) //IntStream
.sum(); // int
This approach simply maps each string to its length and sums them all up.
Upvotes: 1