Home > Back-end >  How does java's double colon operator refer non-static method using class name
How does java's double colon operator refer non-static method using class name

Time:07-21

I have written a code like this:

public class MyClass implements Comparable{

    int value;

    MyClass(int value){
        this.value = value;
    }
    public static void main(String[] args) {

        MyClass obj1 = new MyClass(30);
        MyClass obj2 = new MyClass(5);
        MyClass obj3 = new MyClass(15);
        List<MyClass> classList = new ArrayList<>();
        classList.add(obj1);
        classList.add(obj2);
        classList.add(obj3);

        List<MyClass> list2 =classList.stream().sorted(MyClass::compareTo).collect(Collectors.toList());
        list2.stream().forEach(x-> System.out.println(x.value));

    }

    @Override
    public int compareTo(Object o) {
        MyClass obj = (MyClass)o;
        if(this.value<obj.value){
            return  1;
        }else return -1;
    }
}

This code compiles successfully gives me the correct output as expected-

30
15
5

I have 2 questions

  1. How are we able to refer non-static method compareTo using Myclass(classname)? Shouldn't we be expected to use object of my class to refer compareTo()?

  2. How are we able to use compareTo() method which takes only 1 parameter, whereas sorted() expects Comparator Interface whose abstract class compare() takes 2 parameters?

CodePudding user response:

The Stream method sorted takes a Comparator<T> as parameter. This is a functional interface, so you can use a lambda expression or method reference as parameter that adheres to this interface. The method signature is as follows:

int compare(T var1, T var2);

So, for example, the following lambda expression is valid:

(MyClass a, MyClass b) -> a.compareTo(b)

A method reference can refer to static methods, but in this specific context, the type of the method reference can also replace the first parameter, so the following expression is equivalent to the above:

MyClass::compareTo

Similarly, you can do the following:

(String a, String b) -> a.equals(b)
String::equals

Or things like this:

(String a) -> "b".equals(a)
"b"::equals

CodePudding user response:

List list2 =classList.stream().sorted(MyClass::compareTo).collect(Collectors.toList());

In this line you have used stream.sorted which still is a stream then you have called compareTo method in MyClass for each stream element.

  • Related