I have the following code. Sonar is complaining replace this lambda with a method reference.
Stream.iterate(0, i -> i + 1).limit(100).map(i -> Integer.toString(i));
If I replace it with it code below, it does not compile with compilation error: Type mismatch: cannot convert from Stream<Object>
to <unknown>
.
Stream.iterate(0, i -> i + 1).limit(100).map(Integer::toString);
How is Integer::toString
converting Stream<Object>
to <unknown>
?
You can't put Integer::toString
because Integer
has two implementations that fit to functional interface Function<Integer, String>
, but you can use String::valueOf
instead:
Stream.iterate(0, i -> i + 1)
.limit(100)
.map(String::valueOf)
.collect(Collectors.toList())
As mentioned by @shmosel already replacing the lambda with a method reference will lead to ambiguity as there's two toString
method of the signarure:
String toString()
static String toString(int i)
because the call to Stream.iterate(0, i -> i + 1)
returns a Stream<Integer>
when you call map
with the method reference Integer::toString
the compiler is not sure whether you meant to do Integer.toString(i)
or i.toString()
hence the compilation error.
So here are other options to what's already been provided:
instead of Stream.iterate
you can use IntStream.iterate
then call mapToObj
:
IntStream.iterate(0, i -> i + 1) // IntStream
.limit(100) // IntStream
.mapToObj(Integer::toString); // i1 -> Integer.toString(i1)
Another thing suggested by intelliJ
is that you can actually do:
Stream.iterate(0, i -> i + 1) // Stream<Integer>
.limit(100) // Stream<Integer>
.map(Object::toString); // integer -> integer.toString()
where Object::toString
is equivalent to the lambda integer -> integer.toString()
on another note, it's interesting that Sonar is suggesting to replace the lambda with a method reference in the code you've shown. intelliJ IDEA was smart enough not to suggest it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With