Forum Stats

  • 3,769,403 Users
  • 2,252,961 Discussions
  • 7,875,020 Comments

Discussions

Confused with using method reference in Comparator.comparing()

ABISHEAK S
ABISHEAK S Member Posts: 1 Green Ribbon

Am a self learning developer, now learning Java. I have learned that to use method reference for a Functional Interface, the signature of the method we referring must match the signature of the abstract method inside that functional interface.

But While learning Comparator, found that "Comparator.comparing()" method takes Function interface and returns a Comparator. I know that the abstract method of Function interface must take a argument and return a value.

but I can able to pass any method(as method reference) that partially (not fully) matches the signature of Function interface to the comparing() method of Comparator.

for example consider the below example.

public class Movie {
private  String title;
private int likes;

public Movie(String title, int likes) {
    this.title = title;
    this.likes = likes;
}

public String getTitle(){
    return title;
}

public int getLikes() {
    return likes;
}
}

import java.util.Comparator;
import java.util.List;

public class Main {
public static void main(String[] args) {     
    var movies=List.of(
      new Movie("b", 20),
      new Movie("c", 30),
      new Movie("a", 10));

    var stream=movies.stream().
    sorted(Comparator.comparing(Movie::getTitle));  
    stream.forEach(m->System.out.println(m.getLikes()));
  }
}

Here, in the line "sorted(Comparator.comparing(Movie::getTitle))"

as you see the getTitle() method takes no argument and returns a String value. But it can be used as method reference for the function interface (which takes a argument and returns a value).

Why is it happening ? Please answer anyone to solve my confusion.

Tagged:

Answers

  • Carlos Obregón
    Carlos Obregón Member Posts: 1 Green Ribbon
    edited Sep 22, 2021 12:00PM

    This is a great question!

    The method comparing in its signature says that you need to provide a Function that given a T would return a U type which implements Comparable. Given that what you return is Comparable, the comparing function will call the function twice for the objects being compared and then call the compareTo method of the values returned.

    Movie::getTitle is a Function that matches that criteria: given a Movie it would extract a String, which implements Comparable, and because of that comparing method can easily use to sort the movies. Since you usually have accessors, e.g. getTitle, they are commonly used for comparing method, although you can use any Function as long as it matches the signature.

    I hope this makes sense!