Replace this lambda with a method reference











up vote
7
down vote

favorite












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










share|improve this question




























    up vote
    7
    down vote

    favorite












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










    share|improve this question


























      up vote
      7
      down vote

      favorite









      up vote
      7
      down vote

      favorite











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










      share|improve this question















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







      java java-8 sonarqube java-stream






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 5 hours ago

























      asked 7 hours ago









      fastcodejava

      23.6k19109160




      23.6k19109160
























          4 Answers
          4






          active

          oldest

          votes

















          up vote
          8
          down vote













          It's ambiguous because the static and non-static toString() methods are both compatible with the functional signature Integer -> String. You can use String::valueOf instead.






          share|improve this answer




























            up vote
            5
            down vote













            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())





            share|improve this answer



















            • 1




              You can't put Integer::toString because it accepts int and your case you have Integer use. That's not correct. Lambdas can implicitly box and unbox.
              – shmosel
              7 hours ago












            • @shmosel then why does it IntStream.range(1, 100).mapToObj(Integer::toString).collect(Collectors.toList()) work?
              – vlad324
              7 hours ago












            • Because the int overload is more appropriate for a primitive stream.
              – shmosel
              7 hours ago












            • @shmosel yes, you are right about Lambdas can implicitly box and unbox
              – vlad324
              7 hours ago


















            up vote
            2
            down vote













            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)
            .limit(100)
            .mapToObj(Integer::toString);


            Another thing suggested by intelliJ is that you can actually do:



            Stream.iterate(0, i -> i + 1)
            .limit(100)
            .map(Object::toString); // note the Object


            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.






            share|improve this answer






























              up vote
              0
              down vote













              I think that IntStream is better for your code:



              List<String> numbers = IntStream.range(0, 100)
              .mapToObj(String::valueOf)
              .collect(Collectors.toList());


              Or for your example do use String.valueOf to conver int -> String:



              List<String> numbers = Stream.iterate(0, i -> i + 1)
              .limit(100)
              .map(String::valueOf)
              .collect(Collectors.toList());





              share|improve this answer























                Your Answer






                StackExchange.ifUsing("editor", function () {
                StackExchange.using("externalEditor", function () {
                StackExchange.using("snippets", function () {
                StackExchange.snippets.init();
                });
                });
                }, "code-snippets");

                StackExchange.ready(function() {
                var channelOptions = {
                tags: "".split(" "),
                id: "1"
                };
                initTagRenderer("".split(" "), "".split(" "), channelOptions);

                StackExchange.using("externalEditor", function() {
                // Have to fire editor after snippets, if snippets enabled
                if (StackExchange.settings.snippets.snippetsEnabled) {
                StackExchange.using("snippets", function() {
                createEditor();
                });
                }
                else {
                createEditor();
                }
                });

                function createEditor() {
                StackExchange.prepareEditor({
                heartbeatType: 'answer',
                convertImagesToLinks: true,
                noModals: true,
                showLowRepImageUploadWarning: true,
                reputationToPostImages: 10,
                bindNavPrevention: true,
                postfix: "",
                imageUploader: {
                brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                allowUrls: true
                },
                onDemand: true,
                discardSelector: ".discard-answer"
                ,immediatelyShowMarkdownHelp:true
                });


                }
                });














                draft saved

                draft discarded


















                StackExchange.ready(
                function () {
                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53715187%2freplace-this-lambda-with-a-method-reference%23new-answer', 'question_page');
                }
                );

                Post as a guest















                Required, but never shown

























                4 Answers
                4






                active

                oldest

                votes








                4 Answers
                4






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes








                up vote
                8
                down vote













                It's ambiguous because the static and non-static toString() methods are both compatible with the functional signature Integer -> String. You can use String::valueOf instead.






                share|improve this answer

























                  up vote
                  8
                  down vote













                  It's ambiguous because the static and non-static toString() methods are both compatible with the functional signature Integer -> String. You can use String::valueOf instead.






                  share|improve this answer























                    up vote
                    8
                    down vote










                    up vote
                    8
                    down vote









                    It's ambiguous because the static and non-static toString() methods are both compatible with the functional signature Integer -> String. You can use String::valueOf instead.






                    share|improve this answer












                    It's ambiguous because the static and non-static toString() methods are both compatible with the functional signature Integer -> String. You can use String::valueOf instead.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered 7 hours ago









                    shmosel

                    35.6k43892




                    35.6k43892
























                        up vote
                        5
                        down vote













                        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())





                        share|improve this answer



















                        • 1




                          You can't put Integer::toString because it accepts int and your case you have Integer use. That's not correct. Lambdas can implicitly box and unbox.
                          – shmosel
                          7 hours ago












                        • @shmosel then why does it IntStream.range(1, 100).mapToObj(Integer::toString).collect(Collectors.toList()) work?
                          – vlad324
                          7 hours ago












                        • Because the int overload is more appropriate for a primitive stream.
                          – shmosel
                          7 hours ago












                        • @shmosel yes, you are right about Lambdas can implicitly box and unbox
                          – vlad324
                          7 hours ago















                        up vote
                        5
                        down vote













                        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())





                        share|improve this answer



















                        • 1




                          You can't put Integer::toString because it accepts int and your case you have Integer use. That's not correct. Lambdas can implicitly box and unbox.
                          – shmosel
                          7 hours ago












                        • @shmosel then why does it IntStream.range(1, 100).mapToObj(Integer::toString).collect(Collectors.toList()) work?
                          – vlad324
                          7 hours ago












                        • Because the int overload is more appropriate for a primitive stream.
                          – shmosel
                          7 hours ago












                        • @shmosel yes, you are right about Lambdas can implicitly box and unbox
                          – vlad324
                          7 hours ago













                        up vote
                        5
                        down vote










                        up vote
                        5
                        down vote









                        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())





                        share|improve this answer














                        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())






                        share|improve this answer














                        share|improve this answer



                        share|improve this answer








                        edited 7 hours ago

























                        answered 7 hours ago









                        vlad324

                        53228




                        53228








                        • 1




                          You can't put Integer::toString because it accepts int and your case you have Integer use. That's not correct. Lambdas can implicitly box and unbox.
                          – shmosel
                          7 hours ago












                        • @shmosel then why does it IntStream.range(1, 100).mapToObj(Integer::toString).collect(Collectors.toList()) work?
                          – vlad324
                          7 hours ago












                        • Because the int overload is more appropriate for a primitive stream.
                          – shmosel
                          7 hours ago












                        • @shmosel yes, you are right about Lambdas can implicitly box and unbox
                          – vlad324
                          7 hours ago














                        • 1




                          You can't put Integer::toString because it accepts int and your case you have Integer use. That's not correct. Lambdas can implicitly box and unbox.
                          – shmosel
                          7 hours ago












                        • @shmosel then why does it IntStream.range(1, 100).mapToObj(Integer::toString).collect(Collectors.toList()) work?
                          – vlad324
                          7 hours ago












                        • Because the int overload is more appropriate for a primitive stream.
                          – shmosel
                          7 hours ago












                        • @shmosel yes, you are right about Lambdas can implicitly box and unbox
                          – vlad324
                          7 hours ago








                        1




                        1




                        You can't put Integer::toString because it accepts int and your case you have Integer use. That's not correct. Lambdas can implicitly box and unbox.
                        – shmosel
                        7 hours ago






                        You can't put Integer::toString because it accepts int and your case you have Integer use. That's not correct. Lambdas can implicitly box and unbox.
                        – shmosel
                        7 hours ago














                        @shmosel then why does it IntStream.range(1, 100).mapToObj(Integer::toString).collect(Collectors.toList()) work?
                        – vlad324
                        7 hours ago






                        @shmosel then why does it IntStream.range(1, 100).mapToObj(Integer::toString).collect(Collectors.toList()) work?
                        – vlad324
                        7 hours ago














                        Because the int overload is more appropriate for a primitive stream.
                        – shmosel
                        7 hours ago






                        Because the int overload is more appropriate for a primitive stream.
                        – shmosel
                        7 hours ago














                        @shmosel yes, you are right about Lambdas can implicitly box and unbox
                        – vlad324
                        7 hours ago




                        @shmosel yes, you are right about Lambdas can implicitly box and unbox
                        – vlad324
                        7 hours ago










                        up vote
                        2
                        down vote













                        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)
                        .limit(100)
                        .mapToObj(Integer::toString);


                        Another thing suggested by intelliJ is that you can actually do:



                        Stream.iterate(0, i -> i + 1)
                        .limit(100)
                        .map(Object::toString); // note the Object


                        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.






                        share|improve this answer



























                          up vote
                          2
                          down vote













                          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)
                          .limit(100)
                          .mapToObj(Integer::toString);


                          Another thing suggested by intelliJ is that you can actually do:



                          Stream.iterate(0, i -> i + 1)
                          .limit(100)
                          .map(Object::toString); // note the Object


                          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.






                          share|improve this answer

























                            up vote
                            2
                            down vote










                            up vote
                            2
                            down vote









                            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)
                            .limit(100)
                            .mapToObj(Integer::toString);


                            Another thing suggested by intelliJ is that you can actually do:



                            Stream.iterate(0, i -> i + 1)
                            .limit(100)
                            .map(Object::toString); // note the Object


                            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.






                            share|improve this answer














                            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)
                            .limit(100)
                            .mapToObj(Integer::toString);


                            Another thing suggested by intelliJ is that you can actually do:



                            Stream.iterate(0, i -> i + 1)
                            .limit(100)
                            .map(Object::toString); // note the Object


                            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.







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited 8 mins ago

























                            answered 1 hour ago









                            Aomine

                            35.3k62859




                            35.3k62859






















                                up vote
                                0
                                down vote













                                I think that IntStream is better for your code:



                                List<String> numbers = IntStream.range(0, 100)
                                .mapToObj(String::valueOf)
                                .collect(Collectors.toList());


                                Or for your example do use String.valueOf to conver int -> String:



                                List<String> numbers = Stream.iterate(0, i -> i + 1)
                                .limit(100)
                                .map(String::valueOf)
                                .collect(Collectors.toList());





                                share|improve this answer



























                                  up vote
                                  0
                                  down vote













                                  I think that IntStream is better for your code:



                                  List<String> numbers = IntStream.range(0, 100)
                                  .mapToObj(String::valueOf)
                                  .collect(Collectors.toList());


                                  Or for your example do use String.valueOf to conver int -> String:



                                  List<String> numbers = Stream.iterate(0, i -> i + 1)
                                  .limit(100)
                                  .map(String::valueOf)
                                  .collect(Collectors.toList());





                                  share|improve this answer

























                                    up vote
                                    0
                                    down vote










                                    up vote
                                    0
                                    down vote









                                    I think that IntStream is better for your code:



                                    List<String> numbers = IntStream.range(0, 100)
                                    .mapToObj(String::valueOf)
                                    .collect(Collectors.toList());


                                    Or for your example do use String.valueOf to conver int -> String:



                                    List<String> numbers = Stream.iterate(0, i -> i + 1)
                                    .limit(100)
                                    .map(String::valueOf)
                                    .collect(Collectors.toList());





                                    share|improve this answer














                                    I think that IntStream is better for your code:



                                    List<String> numbers = IntStream.range(0, 100)
                                    .mapToObj(String::valueOf)
                                    .collect(Collectors.toList());


                                    Or for your example do use String.valueOf to conver int -> String:



                                    List<String> numbers = Stream.iterate(0, i -> i + 1)
                                    .limit(100)
                                    .map(String::valueOf)
                                    .collect(Collectors.toList());






                                    share|improve this answer














                                    share|improve this answer



                                    share|improve this answer








                                    edited 36 mins ago

























                                    answered 42 mins ago









                                    oleg.cherednik

                                    4,9092916




                                    4,9092916






























                                        draft saved

                                        draft discarded




















































                                        Thanks for contributing an answer to Stack Overflow!


                                        • Please be sure to answer the question. Provide details and share your research!

                                        But avoid



                                        • Asking for help, clarification, or responding to other answers.

                                        • Making statements based on opinion; back them up with references or personal experience.


                                        To learn more, see our tips on writing great answers.





                                        Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                        Please pay close attention to the following guidance:


                                        • Please be sure to answer the question. Provide details and share your research!

                                        But avoid



                                        • Asking for help, clarification, or responding to other answers.

                                        • Making statements based on opinion; back them up with references or personal experience.


                                        To learn more, see our tips on writing great answers.




                                        draft saved


                                        draft discarded














                                        StackExchange.ready(
                                        function () {
                                        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53715187%2freplace-this-lambda-with-a-method-reference%23new-answer', 'question_page');
                                        }
                                        );

                                        Post as a guest















                                        Required, but never shown





















































                                        Required, but never shown














                                        Required, but never shown












                                        Required, but never shown







                                        Required, but never shown

































                                        Required, but never shown














                                        Required, but never shown












                                        Required, but never shown







                                        Required, but never shown







                                        Popular posts from this blog

                                        Bundesstraße 106

                                        Verónica Boquete

                                        Ida-Boy-Ed-Garten