Java, why collection.sort () still works with an argument not related to a comparator?

I know that in the java Collections class there is a static sort method:

sort(List<T> list, Comparator<? super T> c**) 

The second argument in the sort must be an object that implements the Comparator interface, and it compares the method.

But when I find out the link of the lambda method , I see this example:

 public class Test { public static void main(String[] args) { new Test().sortWord(); } public void sortWord() { List<String> lst = new ArrayList<>(); lst.add("hello"); lst.add("world"); lst.add("apple"); lst.add("zipcode"); Collections.sort(lst, this::compareWord); System.out.println(lst); } public int compareWord(String a, String b) { return a.compareTo(b); } 

}

This is an example method reference for an instance method. The compareWord method has nothing to do with the Comparator interface, I don’t understand why this works? can anyone explain this?

Thank you very much.

+5
source share
3 answers

int compareWord(String a, String b) has the same signature as the int compare(String o1, String o2) method of the Comparator<String> interface. Therefore, it can be used as an implementation of this interface.

This is a shorter way to write:

 Collections.sort(lst, new Comparator<String> () { public int compare (String o1, String o2) { return compareWord(o1,o2); } }); 

In Java 8, any functional interface, such as a Comparator (that is, an interface that has one abstract method), can be implemented using a method method reference that has a signature that matches the signature of the abstract interface method.

+7
source

Here you do not need to write an explicit String Comparator.

Just follow these steps and it should work fine.

 Collections.sort(lst); 

By the way, @Eran explained, the same method signature on compareWord and compare in your scripts.

+1
source

Comparator interface @FunctionalInterface :

A functional interface is an interface that [...] is a contract with a single function. [...]

For an interface, let M be a set of abstract methods that are members of I that do not have the same signature as any method of a public instance of the Object class. Then I am a functional interface if there is a method m in M ​​for which both of the following conditions are true:

  • The signature m is a submission (§8.4.2) of each method signature in M.

  • m is a return type-replaceable (§8.4.5) for each method in M.

In addition to the normal process of instantiating an interface by declaring and instantiating a class ( §15.9 ), instances of functional interfaces can ( §15.13 , §15,27 ).

Comparator is mentioned below as an example:

A functional interface definition excludes methods in an interface that are also public methods in Object. This should allow a functional cure for an interface such as java.util.Comparator, which declares several abstract methods, of which only one is really “new” - int compare (T, T). Another method, boolean equals (Object), is an explicit declaration of an abstract method, which would otherwise be declared implicitly and would be automatically implemented by each class that implements the interface.

Besides the example of the anonymous class provided by @Eran and the method reference expression from the question, the lamba expression will also work:

 Collections.sort(lst, (a, b) -> ...); 
0
source

Source: https://habr.com/ru/post/1271025/


All Articles