Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace this lambda with a method reference [duplicate]

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>?

like image 833
fastcodejava Avatar asked Dec 10 '18 23:12

fastcodejava


2 Answers

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())
like image 184
codeformars Avatar answered Oct 05 '22 23:10

codeformars


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.

like image 38
Ousmane D. Avatar answered Oct 05 '22 22:10

Ousmane D.