While the aforementioned answers are correct and mapToObj
is the idiomatic approach to proceed with, I think it's important to understand why the problem arises and thus in future cases, you'll know how to decipher the problem simply by going through the documentation.
it's a very important skill for a programmer to dig into the documentation when not understanding the workings of a specific method.
So, let's go through the relevant stream pipeline operations:
IntStream.rangeClosed
returns an IntStream
as per the documentation:
Returns a sequential ordered IntStream from startInclusive (inclusive)
to endInclusive (inclusive) by an incremental step of 1.
invoking map
on an IntStream
is expected to return an IntStream
as per the documentation:
Returns a stream consisting of the results of applying the given
function to the elements of this stream.
As well as that it's important to note that the method declaration for map
is as follows:
IntStream map(IntUnaryOperator mapper)
i.e. it takes a IntUnaryOperator
which in fact represents an operation on a single int-valued operand that produces an int-valued result.
However, you're passing a function String::valueOf
which consumes an int
as we're dealing with an IntStream
and returns a String
thus not compliant with IntUnaryOperator
and this is the cause of the problem.
Whenever you want to take a primitive stream specialization and perform some mapping function and in turn yield a Stream<R>
as a result then mapToObj
is the way to go.
mapToObj
is declared as:
mapToObj(IntFunction<? extends U> mapper)
IntFunction
represents a function that accepts an int-valued argument and produces a result and this result is of type R
which means you'll have a Stream<R>
after the mapToObj
.