This article has been included in my collection of articles: gitee.com/mydb/interv...
In the Java language, both Comparable and Comparator are used to sort elements, but they are essentially different. They are also common interview questions, so let's play it together today.
1. Different literal meanings
We first understand it from the literal meaning of the two. Comparable translates into Chinese as "comparison", while Comparator means "Comparator". Comparable ends with - able, indicating that it has certain abilities, while Comparator ends with - or, indicating that it is a comparison participant. This is to understand the difference between the two from the literal meaning.
2. Different usage
Both are top-level interfaces, but they have different methods and usages. Let's look at them separately.
2.1 Comparable
The Comparable interface has only one method compareTo. Implementing the Comparable interface and overriding the compareTo method can realize the sorting of a class. It supports collections Sort and arrays Sort.
When we do not use Comparable, the execution of the program is as follows:
import lombok.Getter; import lombok.Setter; import lombok.ToString; import java.util.ArrayList; import java.util.List; public class ComparableExample { public static void main(String[] args) { // create object Person p1 = new Person(1, 18, "Java"); Person p2 = new Person(2, 22, "MySQL"); Person p3 = new Person(3, 6, "Redis"); // Add to collection List<Person> list = new ArrayList<>(); list.add(p1); list.add(p2); list.add(p3); // Print collection information list.forEach(p -> System.out.println(p.getName() + ": " + p.getAge())); } } // The following set/get/toString uses the annotations provided by lombok @Getter @Setter @ToString class Person { private int id; private int age; private String name; public Person(int id, int age, String name) { this.id = id; this.age = age; this.name = name; } } Copy code
The program execution results are as follows:
As can be seen from the above figure, when the user-defined class Person does not implement Comparable, the List collection is not sorted, and only the insertion order of elements can be used as the output order.
However, at this time, the boss has a demand: you need to reverse the order according to the age attribute of the Person object, that is, sort according to the age attribute from large to small. At this time, you can invite the protagonist of our article: Comparable.
The use of Comparable is to implement the Comparable interface in the class of the custom object and override the compareTo method to implement the custom sorting rules. The specific implementation code is as follows:
import lombok.Getter; import lombok.Setter; import lombok.ToString; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class ComparableExample { public static void main(String[] args) { // create object Person p1 = new Person(1, 18, "Java"); Person p2 = new Person(2, 22, "MySQL"); Person p3 = new Person(3, 6, "Redis"); // Add object to collection List<Person> list = new ArrayList<>(); list.add(p1); list.add(p2); list.add(p3); // Sort (according to the sorting rules defined in compareTo in the Person class) Collections.sort(list); // Order in output set list.forEach(p -> System.out.println(p.getName() + ": " + p.getAge())); } } // The following set/get/toString are implemented using the annotations provided by lombok @Getter @Setter @ToString static class Person implements Comparable<Person> { private int id; private int age; private String name; public Person(int id, int age, String name) { this.id = id; this.age = age; this.name = name; } @Override public int compareTo(Person p) { return p.getAge() - this.getAge(); } } Copy code
The execution results of the program are shown in the following figure:
compareTo sorting method description
The parameter p received by the compareTo method is the object to be compared. The sorting rule is to compare the current object with the object to be compared, and then return an int type value. The sorting rule of positive order from small to large is: subtract the value of the object to be compared from the current object value; The reverse sorting rule from large to small is just the opposite: it subtracts the value of the current object from the value of the comparison object.
Note: if the custom object does not implement the Comparable interface, it cannot use collections For sorting by sort method, the compiler will prompt the following error:
2.2 Comparator
The sorting methods of Comparator and Comparable are different. compareTo is the sorting method of Comparable, while compare is the sorting method of Comparator. The specific implementation code is as follows:
import lombok.Getter; import lombok.Setter; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class ComparatorExample { public static void main(String[] args) { // create object Person p1 = new Person(1, 18, "Java"); Person p2 = new Person(2, 22, "MySQL"); Person p3 = new Person(3, 6, "Redis"); // Add object to collection List<Person> list = new ArrayList<>(); list.add(p1); list.add(p2); list.add(p3); // Sort (according to the sorting rules defined in the person comparator) Collections.sort(list, new PersonComparator()); // Order in output set list.forEach(p -> System.out.println(p.getName() + ": " + p.getAge())); } } /** * Comparator for Person class */ class PersonComparator implements Comparator<Person> { @Override public int compare(Person p1, Person p2) { return p2.getAge() - p1.getAge(); } } @Getter @Setter class Person { private int id; private int age; private String name; public Person(int id, int age, String name) { this.id = id; this.age = age; } } Copy code
The execution results of the program are shown in the following figure:
Extension: Comparator anonymous class
Comparator can not only create a custom comparator, but also complete the function of custom comparator more quickly and conveniently through anonymous classes. The specific code is as follows:
import lombok.Getter; import lombok.Setter; import java.util.ArrayList; import java.util.Comparator; import java.util.List; public class ComparatorExample { public static void main(String[] args) { // Build and add data List<Person> list = new ArrayList<>(); list.add(new Person(1, 18, "Java")); list.add(new Person(2, 20, "MySQL")); list.add(new Person(3, 6, "Redis")); // Sort using the Comparator anonymous class list.sort(new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p2.getAge() - p1.getAge(); } }); // Print set data list.forEach(p -> System.out.println(p.getName() + ": " + p.getAge())); } } @Getter @Setter static class Person { private int id; private int age; private String name; public Person(int id, int age, String name) { this.id = id; this.age = age; this.name = name; } } Copy code
The execution results of the program are shown in the following figure:
3. Different scenarios are used
Through the implementation code of the above example, we can see that the original class must be modified to use Comparable, that is, if you want to sort that class, you need to implement the Comparable interface and rewrite the compareTo method, so Comparable is more like an interface for "internal" sorting.
The use of comparator is different. Comparator does not need to modify the original class. That is, in the most extreme case, even if the Person class is provided by a third party, we can still realize the sorting function of the third party class Person by creating a new custom comparator comparator. In other words, the comparator interface can decouple from the original class and realize the sorting function without modifying the original class. Therefore, the comparator can be regarded as an "external" interface to provide sorting.
summary
Both Comparable and Comparator are used to sort elements. The differences between them are as follows:
- Comparable means "compare" and Comparator means "Comparator";
- Comparable implements sorting by rewriting compareTo method, while Comparator implements sorting by rewriting compare method;
- Comparable must implement the sorting method internally by the custom class, while Comparator defines and implements sorting externally.
Therefore, summarize the difference between the two in one sentence: Comparable can be regarded as the "internal" sorting interface, while Comparator is the "external" sorting interface.