Java 8 stream max() function argument type Comparator vs Comparable Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern) The Ask Question Wizard is Live! Data science time! April 2019 and salary with experience Should we burninate the [wrap] tag?Java 8 stream's .min() and .max(): why does this compile?How do I compare strings in Java?Comparing Java enum members: == or equals()?Best practice for compareTo() when argument must be typed of super classIs there a concise way to iterate over a stream with indices in Java 8?Custom thread pool in Java 8 parallel streamHow to Convert a Java 8 Stream to an Array?Convert Iterable to Stream using Java 8 JDKWhy are Java Streams once-off?How to sum a list of integers with java streams?Java Generics Clarification( Constraining T to a type, while using Comparable)

Should gear shift center itself while in neutral?

How to recreate this effect in Photoshop?

If a contract sometimes uses the wrong name, is it still valid?

How do I stop a creek from eroding my steep embankment?

Can inflation occur in a positive-sum game currency system such as the Stack Exchange reputation system?

Disable hyphenation for an entire paragraph

How to draw this diagram using TikZ package?

Do you forfeit tax refunds/credits if you aren't required to and don't file by April 15?

"Seemed to had" is it correct?

List *all* the tuples!

Is above average number of years spent on PhD considered a red flag in future academia or industry positions?

What happens to sewage if there is no river near by?

Should I call the interviewer directly, if HR aren't responding?

Output the ŋarâþ crîþ alphabet song without using (m)any letters

Is it true that "carbohydrates are of no use for the basal metabolic need"?

Bonus calculation: Am I making a mountain out of a molehill?

Is there a Spanish version of "dot your i's and cross your t's" that includes the letter 'ñ'?

How to bypass password on Windows XP account?

How widely used is the term Treppenwitz? Is it something that most Germans know?

When is phishing education going too far?

Withdrew £2800, but only £2000 shows as withdrawn on online banking; what are my obligations?

Does accepting a pardon have any bearing on trying that person for the same crime in a sovereign jurisdiction?

If 'B is more likely given A', then 'A is more likely given B'

Doubts about chords



Java 8 stream max() function argument type Comparator vs Comparable



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)
The Ask Question Wizard is Live!
Data science time! April 2019 and salary with experience
Should we burninate the [wrap] tag?Java 8 stream's .min() and .max(): why does this compile?How do I compare strings in Java?Comparing Java enum members: == or equals()?Best practice for compareTo() when argument must be typed of super classIs there a concise way to iterate over a stream with indices in Java 8?Custom thread pool in Java 8 parallel streamHow to Convert a Java 8 Stream to an Array?Convert Iterable to Stream using Java 8 JDKWhy are Java Streams once-off?How to sum a list of integers with java streams?Java Generics Clarification( Constraining T to a type, while using Comparable)



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








11















I wrote some simple code like below. This class works fine without any errors.



public class Test 
public static void main(String[] args)
List<Integer> intList = IntStream.of(1,2,3,4,5,6,7,8,9,10).boxed().collect(Collectors.toList());
int value = intList.stream().max(Integer::compareTo).get();

//int value = intList.stream().max(<Comparator<? super T> comparator type should pass here>).get();

System.out.println("value :"+value);




As the code comment shows the max() method should pass an argument of type Comparator<? super Integer>.



But Integer::compareTo implements Comparable interface - not Comparator.



public final class Integer extends Number implements Comparable<Integer> 
public int compareTo(Integer anotherInteger)
return compare(this.value, anotherInteger.value);




How can this work? The max() method says it needs a Comparator argument, but it works with Comparable argument.



I know I have misunderstood something, but I do now know what. Can someone please explain?










share|improve this question



















  • 2





    Integer::compareTo does not return a Comparable - it is the short definition for: "Please compiler generate a matching implementation for the type that is needed (in this case Comparator) and map the arguments to the specified function." In this case the function requires two "arguments" (this and the one parameter of compareTo) and the Comparator provides two arguments -> works.

    – Robert
    7 hours ago







  • 4





    ""Please compiler, generate..." ... compilers always respond best to politeness and courtesy :-)

    – scottb
    7 hours ago











  • Related: stackoverflow.com/questions/22561614/…

    – Oleksandr
    3 hours ago

















11















I wrote some simple code like below. This class works fine without any errors.



public class Test 
public static void main(String[] args)
List<Integer> intList = IntStream.of(1,2,3,4,5,6,7,8,9,10).boxed().collect(Collectors.toList());
int value = intList.stream().max(Integer::compareTo).get();

//int value = intList.stream().max(<Comparator<? super T> comparator type should pass here>).get();

System.out.println("value :"+value);




As the code comment shows the max() method should pass an argument of type Comparator<? super Integer>.



But Integer::compareTo implements Comparable interface - not Comparator.



public final class Integer extends Number implements Comparable<Integer> 
public int compareTo(Integer anotherInteger)
return compare(this.value, anotherInteger.value);




How can this work? The max() method says it needs a Comparator argument, but it works with Comparable argument.



I know I have misunderstood something, but I do now know what. Can someone please explain?










share|improve this question



















  • 2





    Integer::compareTo does not return a Comparable - it is the short definition for: "Please compiler generate a matching implementation for the type that is needed (in this case Comparator) and map the arguments to the specified function." In this case the function requires two "arguments" (this and the one parameter of compareTo) and the Comparator provides two arguments -> works.

    – Robert
    7 hours ago







  • 4





    ""Please compiler, generate..." ... compilers always respond best to politeness and courtesy :-)

    – scottb
    7 hours ago











  • Related: stackoverflow.com/questions/22561614/…

    – Oleksandr
    3 hours ago













11












11








11


3






I wrote some simple code like below. This class works fine without any errors.



public class Test 
public static void main(String[] args)
List<Integer> intList = IntStream.of(1,2,3,4,5,6,7,8,9,10).boxed().collect(Collectors.toList());
int value = intList.stream().max(Integer::compareTo).get();

//int value = intList.stream().max(<Comparator<? super T> comparator type should pass here>).get();

System.out.println("value :"+value);




As the code comment shows the max() method should pass an argument of type Comparator<? super Integer>.



But Integer::compareTo implements Comparable interface - not Comparator.



public final class Integer extends Number implements Comparable<Integer> 
public int compareTo(Integer anotherInteger)
return compare(this.value, anotherInteger.value);




How can this work? The max() method says it needs a Comparator argument, but it works with Comparable argument.



I know I have misunderstood something, but I do now know what. Can someone please explain?










share|improve this question
















I wrote some simple code like below. This class works fine without any errors.



public class Test 
public static void main(String[] args)
List<Integer> intList = IntStream.of(1,2,3,4,5,6,7,8,9,10).boxed().collect(Collectors.toList());
int value = intList.stream().max(Integer::compareTo).get();

//int value = intList.stream().max(<Comparator<? super T> comparator type should pass here>).get();

System.out.println("value :"+value);




As the code comment shows the max() method should pass an argument of type Comparator<? super Integer>.



But Integer::compareTo implements Comparable interface - not Comparator.



public final class Integer extends Number implements Comparable<Integer> 
public int compareTo(Integer anotherInteger)
return compare(this.value, anotherInteger.value);




How can this work? The max() method says it needs a Comparator argument, but it works with Comparable argument.



I know I have misunderstood something, but I do now know what. Can someone please explain?







java java-8 java-stream






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 6 hours ago









MyStackRunnethOver

1,007919




1,007919










asked 9 hours ago









ShalikaShalika

3931518




3931518







  • 2





    Integer::compareTo does not return a Comparable - it is the short definition for: "Please compiler generate a matching implementation for the type that is needed (in this case Comparator) and map the arguments to the specified function." In this case the function requires two "arguments" (this and the one parameter of compareTo) and the Comparator provides two arguments -> works.

    – Robert
    7 hours ago







  • 4





    ""Please compiler, generate..." ... compilers always respond best to politeness and courtesy :-)

    – scottb
    7 hours ago











  • Related: stackoverflow.com/questions/22561614/…

    – Oleksandr
    3 hours ago












  • 2





    Integer::compareTo does not return a Comparable - it is the short definition for: "Please compiler generate a matching implementation for the type that is needed (in this case Comparator) and map the arguments to the specified function." In this case the function requires two "arguments" (this and the one parameter of compareTo) and the Comparator provides two arguments -> works.

    – Robert
    7 hours ago







  • 4





    ""Please compiler, generate..." ... compilers always respond best to politeness and courtesy :-)

    – scottb
    7 hours ago











  • Related: stackoverflow.com/questions/22561614/…

    – Oleksandr
    3 hours ago







2




2





Integer::compareTo does not return a Comparable - it is the short definition for: "Please compiler generate a matching implementation for the type that is needed (in this case Comparator) and map the arguments to the specified function." In this case the function requires two "arguments" (this and the one parameter of compareTo) and the Comparator provides two arguments -> works.

– Robert
7 hours ago






Integer::compareTo does not return a Comparable - it is the short definition for: "Please compiler generate a matching implementation for the type that is needed (in this case Comparator) and map the arguments to the specified function." In this case the function requires two "arguments" (this and the one parameter of compareTo) and the Comparator provides two arguments -> works.

– Robert
7 hours ago





4




4





""Please compiler, generate..." ... compilers always respond best to politeness and courtesy :-)

– scottb
7 hours ago





""Please compiler, generate..." ... compilers always respond best to politeness and courtesy :-)

– scottb
7 hours ago













Related: stackoverflow.com/questions/22561614/…

– Oleksandr
3 hours ago





Related: stackoverflow.com/questions/22561614/…

– Oleksandr
3 hours ago












3 Answers
3






active

oldest

votes


















11














int value = intList.stream().max(Integer::compareTo).get();


The above snippet of code is logically equivalent to the following:



int value = intList.stream().max((a, b) -> a.compareTo(b)).get();


Which is also logically equivalent to the following:



int value = intList.stream().max(new Comparator<Integer>() 
@Override
public int compare(Integer a, Integer b)
return a.compareTo(b);

).get();


Comparator is a functional interface and can be used as a lambda or method reference, which is why your code compiles and executes successfully.



I recommend reading Oracle's tutorial on Method References (they use an example where two objects are compared) as well as the Java Language Specification on §15.13. Method Reference Expressions to understand why this works.






share|improve this answer




















  • 8





    Although it's absolutely correct, it doesn't answer "How can this work?"

    – Andrew Tobilko
    8 hours ago


















8














I can relate to your confusion.



We've got a Comparator's method which declares two parameters



int compare(T o1, T o2);


and we've got an Integer's method which takes one parameter



int compareTo(Integer anotherInteger)


How on earth does Integer::compareTo get resolved to a Comparator instance?



When a method reference points to an instance method, the parser can look for methods with arity n-1 (n is the expected number of parameters).



Here's an excerpt from the JLS on how applicable methods are identified. I will drop the first part about parsing the expression preceding the :: token.




Second, given a targeted function type with n parameters, a set of potentially applicable methods is identified:



If the method reference expression has the form ReferenceType :: [TypeArguments] Identifier, then the potentially applicable methods are:



  • the member methods of the type to search that would be potentially applicable (§15.12.2.1) for a method invocation which names Identifier, has arity n, has type arguments TypeArguments, and appears in the same class as the method reference expression; plus


  • the member methods of the type to search that would be potentially applicable for a method invocation which names Identifier, has arity n-1, has type arguments TypeArguments, and appears in the same class as the method reference expression.


Two different arities, n and n-1, are considered, to account for the possibility that this form refers to either a static method or an instance method.



...



A method reference expression of the form ReferenceType :: [TypeArguments] Identifier can be interpreted in different ways. If Identifier refers to an instance method, then the implicit lambda expression has an extra parameter compared to if Identifier refers to a static method.



https://docs.oracle.com/javase/specs/jls/se12/html/jls-15.html#jls-15.13.1




If we were to write an implicit lambda expression from that method reference, the first (implicit) parameter would be an instance to call the method on, the second (explicit) parameter would be an argument to pass in the method.



(implicitParam, anotherInteger) -> implicitParam.compareTo(anotherInteger)


Note that a method reference differs from a lambda expression, even though the former can be easily transformed into the latter. A lambda expression needs to be desugared into a new method, while a method reference usually requires only loading a corresponding constant method handle.






share|improve this answer
































    5














    Integer implements Comparable by overriding compareTo.



    That overriden compareTo, however, can be used in a way that satisfies and implements the Comparator interface.



    In its usage here



    int value = intList.stream().max(Integer::compareTo).get();


    it's translated to something like



    int value = intList.stream().max(new Comparator<Integer>() 
    @Override
    public int compare(Integer o1, Integer o2)
    return o1.compareTo(o2);

    ).get();


    A method reference (or lambda expression) must satisfy the signature of the corresponding functional interface's single abstract method and, in this case (Comparator), compareTo does.




    The idea is that max expects a Comparator and its compare method expects two Integer objects. Integer::compareTo can satisfy those expectations because it also expects two Integer objects. The first is its receiver (the instance on which the method is to be called) and the second is the argument. With the new Java 8 syntax, the compiler translates one style to the other.



    (compareTo also returns an int as required by Comparator#compare.)






    share|improve this answer

























    • how does Integer::compareTo satisfy the signature of Comparator#compare? compareTo(Integer) vs compare(Integer, Integer)?

      – Andrew Tobilko
      4 hours ago












    • @AndrewTobilko Edited with an explanation.

      – Savior
      4 hours ago











    • Did I explain it incorrectly (downvote?)?

      – Savior
      3 hours ago












    • I didn’t downvote your answer, though I disagree with the part about the compiler translating something into something else

      – Andrew Tobilko
      3 hours ago












    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',
    autoActivateHeartbeat: false,
    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%2f55694015%2fjava-8-stream-max-function-argument-type-comparator-vs-comparable%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    11














    int value = intList.stream().max(Integer::compareTo).get();


    The above snippet of code is logically equivalent to the following:



    int value = intList.stream().max((a, b) -> a.compareTo(b)).get();


    Which is also logically equivalent to the following:



    int value = intList.stream().max(new Comparator<Integer>() 
    @Override
    public int compare(Integer a, Integer b)
    return a.compareTo(b);

    ).get();


    Comparator is a functional interface and can be used as a lambda or method reference, which is why your code compiles and executes successfully.



    I recommend reading Oracle's tutorial on Method References (they use an example where two objects are compared) as well as the Java Language Specification on §15.13. Method Reference Expressions to understand why this works.






    share|improve this answer




















    • 8





      Although it's absolutely correct, it doesn't answer "How can this work?"

      – Andrew Tobilko
      8 hours ago















    11














    int value = intList.stream().max(Integer::compareTo).get();


    The above snippet of code is logically equivalent to the following:



    int value = intList.stream().max((a, b) -> a.compareTo(b)).get();


    Which is also logically equivalent to the following:



    int value = intList.stream().max(new Comparator<Integer>() 
    @Override
    public int compare(Integer a, Integer b)
    return a.compareTo(b);

    ).get();


    Comparator is a functional interface and can be used as a lambda or method reference, which is why your code compiles and executes successfully.



    I recommend reading Oracle's tutorial on Method References (they use an example where two objects are compared) as well as the Java Language Specification on §15.13. Method Reference Expressions to understand why this works.






    share|improve this answer




















    • 8





      Although it's absolutely correct, it doesn't answer "How can this work?"

      – Andrew Tobilko
      8 hours ago













    11












    11








    11







    int value = intList.stream().max(Integer::compareTo).get();


    The above snippet of code is logically equivalent to the following:



    int value = intList.stream().max((a, b) -> a.compareTo(b)).get();


    Which is also logically equivalent to the following:



    int value = intList.stream().max(new Comparator<Integer>() 
    @Override
    public int compare(Integer a, Integer b)
    return a.compareTo(b);

    ).get();


    Comparator is a functional interface and can be used as a lambda or method reference, which is why your code compiles and executes successfully.



    I recommend reading Oracle's tutorial on Method References (they use an example where two objects are compared) as well as the Java Language Specification on §15.13. Method Reference Expressions to understand why this works.






    share|improve this answer















    int value = intList.stream().max(Integer::compareTo).get();


    The above snippet of code is logically equivalent to the following:



    int value = intList.stream().max((a, b) -> a.compareTo(b)).get();


    Which is also logically equivalent to the following:



    int value = intList.stream().max(new Comparator<Integer>() 
    @Override
    public int compare(Integer a, Integer b)
    return a.compareTo(b);

    ).get();


    Comparator is a functional interface and can be used as a lambda or method reference, which is why your code compiles and executes successfully.



    I recommend reading Oracle's tutorial on Method References (they use an example where two objects are compared) as well as the Java Language Specification on §15.13. Method Reference Expressions to understand why this works.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 8 hours ago

























    answered 9 hours ago









    Jacob G.Jacob G.

    16.8k52466




    16.8k52466







    • 8





      Although it's absolutely correct, it doesn't answer "How can this work?"

      – Andrew Tobilko
      8 hours ago












    • 8





      Although it's absolutely correct, it doesn't answer "How can this work?"

      – Andrew Tobilko
      8 hours ago







    8




    8





    Although it's absolutely correct, it doesn't answer "How can this work?"

    – Andrew Tobilko
    8 hours ago





    Although it's absolutely correct, it doesn't answer "How can this work?"

    – Andrew Tobilko
    8 hours ago













    8














    I can relate to your confusion.



    We've got a Comparator's method which declares two parameters



    int compare(T o1, T o2);


    and we've got an Integer's method which takes one parameter



    int compareTo(Integer anotherInteger)


    How on earth does Integer::compareTo get resolved to a Comparator instance?



    When a method reference points to an instance method, the parser can look for methods with arity n-1 (n is the expected number of parameters).



    Here's an excerpt from the JLS on how applicable methods are identified. I will drop the first part about parsing the expression preceding the :: token.




    Second, given a targeted function type with n parameters, a set of potentially applicable methods is identified:



    If the method reference expression has the form ReferenceType :: [TypeArguments] Identifier, then the potentially applicable methods are:



    • the member methods of the type to search that would be potentially applicable (§15.12.2.1) for a method invocation which names Identifier, has arity n, has type arguments TypeArguments, and appears in the same class as the method reference expression; plus


    • the member methods of the type to search that would be potentially applicable for a method invocation which names Identifier, has arity n-1, has type arguments TypeArguments, and appears in the same class as the method reference expression.


    Two different arities, n and n-1, are considered, to account for the possibility that this form refers to either a static method or an instance method.



    ...



    A method reference expression of the form ReferenceType :: [TypeArguments] Identifier can be interpreted in different ways. If Identifier refers to an instance method, then the implicit lambda expression has an extra parameter compared to if Identifier refers to a static method.



    https://docs.oracle.com/javase/specs/jls/se12/html/jls-15.html#jls-15.13.1




    If we were to write an implicit lambda expression from that method reference, the first (implicit) parameter would be an instance to call the method on, the second (explicit) parameter would be an argument to pass in the method.



    (implicitParam, anotherInteger) -> implicitParam.compareTo(anotherInteger)


    Note that a method reference differs from a lambda expression, even though the former can be easily transformed into the latter. A lambda expression needs to be desugared into a new method, while a method reference usually requires only loading a corresponding constant method handle.






    share|improve this answer





























      8














      I can relate to your confusion.



      We've got a Comparator's method which declares two parameters



      int compare(T o1, T o2);


      and we've got an Integer's method which takes one parameter



      int compareTo(Integer anotherInteger)


      How on earth does Integer::compareTo get resolved to a Comparator instance?



      When a method reference points to an instance method, the parser can look for methods with arity n-1 (n is the expected number of parameters).



      Here's an excerpt from the JLS on how applicable methods are identified. I will drop the first part about parsing the expression preceding the :: token.




      Second, given a targeted function type with n parameters, a set of potentially applicable methods is identified:



      If the method reference expression has the form ReferenceType :: [TypeArguments] Identifier, then the potentially applicable methods are:



      • the member methods of the type to search that would be potentially applicable (§15.12.2.1) for a method invocation which names Identifier, has arity n, has type arguments TypeArguments, and appears in the same class as the method reference expression; plus


      • the member methods of the type to search that would be potentially applicable for a method invocation which names Identifier, has arity n-1, has type arguments TypeArguments, and appears in the same class as the method reference expression.


      Two different arities, n and n-1, are considered, to account for the possibility that this form refers to either a static method or an instance method.



      ...



      A method reference expression of the form ReferenceType :: [TypeArguments] Identifier can be interpreted in different ways. If Identifier refers to an instance method, then the implicit lambda expression has an extra parameter compared to if Identifier refers to a static method.



      https://docs.oracle.com/javase/specs/jls/se12/html/jls-15.html#jls-15.13.1




      If we were to write an implicit lambda expression from that method reference, the first (implicit) parameter would be an instance to call the method on, the second (explicit) parameter would be an argument to pass in the method.



      (implicitParam, anotherInteger) -> implicitParam.compareTo(anotherInteger)


      Note that a method reference differs from a lambda expression, even though the former can be easily transformed into the latter. A lambda expression needs to be desugared into a new method, while a method reference usually requires only loading a corresponding constant method handle.






      share|improve this answer



























        8












        8








        8







        I can relate to your confusion.



        We've got a Comparator's method which declares two parameters



        int compare(T o1, T o2);


        and we've got an Integer's method which takes one parameter



        int compareTo(Integer anotherInteger)


        How on earth does Integer::compareTo get resolved to a Comparator instance?



        When a method reference points to an instance method, the parser can look for methods with arity n-1 (n is the expected number of parameters).



        Here's an excerpt from the JLS on how applicable methods are identified. I will drop the first part about parsing the expression preceding the :: token.




        Second, given a targeted function type with n parameters, a set of potentially applicable methods is identified:



        If the method reference expression has the form ReferenceType :: [TypeArguments] Identifier, then the potentially applicable methods are:



        • the member methods of the type to search that would be potentially applicable (§15.12.2.1) for a method invocation which names Identifier, has arity n, has type arguments TypeArguments, and appears in the same class as the method reference expression; plus


        • the member methods of the type to search that would be potentially applicable for a method invocation which names Identifier, has arity n-1, has type arguments TypeArguments, and appears in the same class as the method reference expression.


        Two different arities, n and n-1, are considered, to account for the possibility that this form refers to either a static method or an instance method.



        ...



        A method reference expression of the form ReferenceType :: [TypeArguments] Identifier can be interpreted in different ways. If Identifier refers to an instance method, then the implicit lambda expression has an extra parameter compared to if Identifier refers to a static method.



        https://docs.oracle.com/javase/specs/jls/se12/html/jls-15.html#jls-15.13.1




        If we were to write an implicit lambda expression from that method reference, the first (implicit) parameter would be an instance to call the method on, the second (explicit) parameter would be an argument to pass in the method.



        (implicitParam, anotherInteger) -> implicitParam.compareTo(anotherInteger)


        Note that a method reference differs from a lambda expression, even though the former can be easily transformed into the latter. A lambda expression needs to be desugared into a new method, while a method reference usually requires only loading a corresponding constant method handle.






        share|improve this answer















        I can relate to your confusion.



        We've got a Comparator's method which declares two parameters



        int compare(T o1, T o2);


        and we've got an Integer's method which takes one parameter



        int compareTo(Integer anotherInteger)


        How on earth does Integer::compareTo get resolved to a Comparator instance?



        When a method reference points to an instance method, the parser can look for methods with arity n-1 (n is the expected number of parameters).



        Here's an excerpt from the JLS on how applicable methods are identified. I will drop the first part about parsing the expression preceding the :: token.




        Second, given a targeted function type with n parameters, a set of potentially applicable methods is identified:



        If the method reference expression has the form ReferenceType :: [TypeArguments] Identifier, then the potentially applicable methods are:



        • the member methods of the type to search that would be potentially applicable (§15.12.2.1) for a method invocation which names Identifier, has arity n, has type arguments TypeArguments, and appears in the same class as the method reference expression; plus


        • the member methods of the type to search that would be potentially applicable for a method invocation which names Identifier, has arity n-1, has type arguments TypeArguments, and appears in the same class as the method reference expression.


        Two different arities, n and n-1, are considered, to account for the possibility that this form refers to either a static method or an instance method.



        ...



        A method reference expression of the form ReferenceType :: [TypeArguments] Identifier can be interpreted in different ways. If Identifier refers to an instance method, then the implicit lambda expression has an extra parameter compared to if Identifier refers to a static method.



        https://docs.oracle.com/javase/specs/jls/se12/html/jls-15.html#jls-15.13.1




        If we were to write an implicit lambda expression from that method reference, the first (implicit) parameter would be an instance to call the method on, the second (explicit) parameter would be an argument to pass in the method.



        (implicitParam, anotherInteger) -> implicitParam.compareTo(anotherInteger)


        Note that a method reference differs from a lambda expression, even though the former can be easily transformed into the latter. A lambda expression needs to be desugared into a new method, while a method reference usually requires only loading a corresponding constant method handle.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 6 hours ago

























        answered 8 hours ago









        Andrew TobilkoAndrew Tobilko

        28.8k104591




        28.8k104591





















            5














            Integer implements Comparable by overriding compareTo.



            That overriden compareTo, however, can be used in a way that satisfies and implements the Comparator interface.



            In its usage here



            int value = intList.stream().max(Integer::compareTo).get();


            it's translated to something like



            int value = intList.stream().max(new Comparator<Integer>() 
            @Override
            public int compare(Integer o1, Integer o2)
            return o1.compareTo(o2);

            ).get();


            A method reference (or lambda expression) must satisfy the signature of the corresponding functional interface's single abstract method and, in this case (Comparator), compareTo does.




            The idea is that max expects a Comparator and its compare method expects two Integer objects. Integer::compareTo can satisfy those expectations because it also expects two Integer objects. The first is its receiver (the instance on which the method is to be called) and the second is the argument. With the new Java 8 syntax, the compiler translates one style to the other.



            (compareTo also returns an int as required by Comparator#compare.)






            share|improve this answer

























            • how does Integer::compareTo satisfy the signature of Comparator#compare? compareTo(Integer) vs compare(Integer, Integer)?

              – Andrew Tobilko
              4 hours ago












            • @AndrewTobilko Edited with an explanation.

              – Savior
              4 hours ago











            • Did I explain it incorrectly (downvote?)?

              – Savior
              3 hours ago












            • I didn’t downvote your answer, though I disagree with the part about the compiler translating something into something else

              – Andrew Tobilko
              3 hours ago
















            5














            Integer implements Comparable by overriding compareTo.



            That overriden compareTo, however, can be used in a way that satisfies and implements the Comparator interface.



            In its usage here



            int value = intList.stream().max(Integer::compareTo).get();


            it's translated to something like



            int value = intList.stream().max(new Comparator<Integer>() 
            @Override
            public int compare(Integer o1, Integer o2)
            return o1.compareTo(o2);

            ).get();


            A method reference (or lambda expression) must satisfy the signature of the corresponding functional interface's single abstract method and, in this case (Comparator), compareTo does.




            The idea is that max expects a Comparator and its compare method expects two Integer objects. Integer::compareTo can satisfy those expectations because it also expects two Integer objects. The first is its receiver (the instance on which the method is to be called) and the second is the argument. With the new Java 8 syntax, the compiler translates one style to the other.



            (compareTo also returns an int as required by Comparator#compare.)






            share|improve this answer

























            • how does Integer::compareTo satisfy the signature of Comparator#compare? compareTo(Integer) vs compare(Integer, Integer)?

              – Andrew Tobilko
              4 hours ago












            • @AndrewTobilko Edited with an explanation.

              – Savior
              4 hours ago











            • Did I explain it incorrectly (downvote?)?

              – Savior
              3 hours ago












            • I didn’t downvote your answer, though I disagree with the part about the compiler translating something into something else

              – Andrew Tobilko
              3 hours ago














            5












            5








            5







            Integer implements Comparable by overriding compareTo.



            That overriden compareTo, however, can be used in a way that satisfies and implements the Comparator interface.



            In its usage here



            int value = intList.stream().max(Integer::compareTo).get();


            it's translated to something like



            int value = intList.stream().max(new Comparator<Integer>() 
            @Override
            public int compare(Integer o1, Integer o2)
            return o1.compareTo(o2);

            ).get();


            A method reference (or lambda expression) must satisfy the signature of the corresponding functional interface's single abstract method and, in this case (Comparator), compareTo does.




            The idea is that max expects a Comparator and its compare method expects two Integer objects. Integer::compareTo can satisfy those expectations because it also expects two Integer objects. The first is its receiver (the instance on which the method is to be called) and the second is the argument. With the new Java 8 syntax, the compiler translates one style to the other.



            (compareTo also returns an int as required by Comparator#compare.)






            share|improve this answer















            Integer implements Comparable by overriding compareTo.



            That overriden compareTo, however, can be used in a way that satisfies and implements the Comparator interface.



            In its usage here



            int value = intList.stream().max(Integer::compareTo).get();


            it's translated to something like



            int value = intList.stream().max(new Comparator<Integer>() 
            @Override
            public int compare(Integer o1, Integer o2)
            return o1.compareTo(o2);

            ).get();


            A method reference (or lambda expression) must satisfy the signature of the corresponding functional interface's single abstract method and, in this case (Comparator), compareTo does.




            The idea is that max expects a Comparator and its compare method expects two Integer objects. Integer::compareTo can satisfy those expectations because it also expects two Integer objects. The first is its receiver (the instance on which the method is to be called) and the second is the argument. With the new Java 8 syntax, the compiler translates one style to the other.



            (compareTo also returns an int as required by Comparator#compare.)







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 3 hours ago

























            answered 9 hours ago









            SaviorSavior

            1,60021331




            1,60021331












            • how does Integer::compareTo satisfy the signature of Comparator#compare? compareTo(Integer) vs compare(Integer, Integer)?

              – Andrew Tobilko
              4 hours ago












            • @AndrewTobilko Edited with an explanation.

              – Savior
              4 hours ago











            • Did I explain it incorrectly (downvote?)?

              – Savior
              3 hours ago












            • I didn’t downvote your answer, though I disagree with the part about the compiler translating something into something else

              – Andrew Tobilko
              3 hours ago


















            • how does Integer::compareTo satisfy the signature of Comparator#compare? compareTo(Integer) vs compare(Integer, Integer)?

              – Andrew Tobilko
              4 hours ago












            • @AndrewTobilko Edited with an explanation.

              – Savior
              4 hours ago











            • Did I explain it incorrectly (downvote?)?

              – Savior
              3 hours ago












            • I didn’t downvote your answer, though I disagree with the part about the compiler translating something into something else

              – Andrew Tobilko
              3 hours ago

















            how does Integer::compareTo satisfy the signature of Comparator#compare? compareTo(Integer) vs compare(Integer, Integer)?

            – Andrew Tobilko
            4 hours ago






            how does Integer::compareTo satisfy the signature of Comparator#compare? compareTo(Integer) vs compare(Integer, Integer)?

            – Andrew Tobilko
            4 hours ago














            @AndrewTobilko Edited with an explanation.

            – Savior
            4 hours ago





            @AndrewTobilko Edited with an explanation.

            – Savior
            4 hours ago













            Did I explain it incorrectly (downvote?)?

            – Savior
            3 hours ago






            Did I explain it incorrectly (downvote?)?

            – Savior
            3 hours ago














            I didn’t downvote your answer, though I disagree with the part about the compiler translating something into something else

            – Andrew Tobilko
            3 hours ago






            I didn’t downvote your answer, though I disagree with the part about the compiler translating something into something else

            – Andrew Tobilko
            3 hours ago


















            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.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55694015%2fjava-8-stream-max-function-argument-type-comparator-vs-comparable%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

            How to create a command for the “strange m” symbol in latex? Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)How do you make your own symbol when Detexify fails?Writing bold small caps with mathpazo packageplus-minus symbol with parenthesis around the minus signGreek character in Beamer document titleHow to create dashed right arrow over symbol?Currency symbol: Turkish LiraDouble prec as a single symbol?Plus Sign Too Big; How to Call adfbullet?Is there a TeX macro for three-legged pi?How do I get my integral-like symbol to align like the integral?How to selectively substitute a letter with another symbol representing the same letterHow do I generate a less than symbol and vertical bar that are the same height?

            Българска екзархия Съдържание История | Български екзарси | Вижте също | Външни препратки | Литература | Бележки | НавигацияУстав за управлението на българската екзархия. Цариград, 1870Слово на Ловешкия митрополит Иларион при откриването на Българския народен събор в Цариград на 23. II. 1870 г.Българската правда и гръцката кривда. От С. М. (= Софийски Мелетий). Цариград, 1872Предстоятели на Българската екзархияПодмененият ВеликденИнформационна агенция „Фокус“Димитър Ризов. Българите в техните исторически, етнографически и политически граници (Атлас съдържащ 40 карти). Berlin, Königliche Hoflithographie, Hof-Buch- und -Steindruckerei Wilhelm Greve, 1917Report of the International Commission to Inquire into the Causes and Conduct of the Balkan Wars

            Category:Tremithousa Media in category "Tremithousa"Navigation menuUpload media34° 49′ 02.7″ N, 32° 26′ 37.32″ EOpenStreetMapGoogle EarthProximityramaReasonatorScholiaStatisticsWikiShootMe