The difference between Comparable and Comparator

1.Comparable

Before we begin, let’s look at a set of code:

We have a People class that contains Name and Age attributes. We compare the sizes of two students. We found that the two reference variables (storage addresses) cannot be compared using the greater than or less sign. The current conclusion is that these two students cannot Comparatively, otherwise the above error will appear.

And what we want is: to make these two objects comparable.

The question that needs to be addressed is: based on what comparison, age? Name?

Here we need an interface: Comparable

Comparable is a sorting interface. You need to implement the comparable interface in the class you want to sort. That means you must first write a method in the class you want to sort to declare the rules according to which attributes we want to sort in the class.

Note: Use compareTo() in the comparable interface to formulate rules, and the compareTo() method is the only method of comparable.

Let’s first take a look at the source code of comparable:

<>Inside is the type to be compared

Here we use the Comparable interface to implement the above code:

class Student implements Comparable<Student> {
    public String name;
    public int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

   //Rewrite compareTo()
    @Override
    public int compareTo(Student o) {
        if (this.age > o.age) {
            return 1;
        } else if (this.age == o.age) {
            return 0;
        } else {
            return -1;
        }
    }
}
public class Test {
    public static void main(String[] args) {
        //Comparing the size of two reference variables in Java cannot use the greater than sign or less than sign to compare
        Student student1 = new Student("zhangsan", 99);
        Student student2 = new Student("lisi", 59);
        //Usage of compareTo()
        System.out.println(student1.compareTo(student2));
        System.out.println("=================================");
        System.out.println(student2.compareTo(student1));
        System.out.println("=================================");
        System.out.println(student2.compareTo(student2));
    }
}





//The above is based on age comparison, cannot be modified, and is in the class

The running results are as follows:

(This kind of intrusion into classes is relatively strong. Once the prescribed comparison method is written, comparisons can only be made in this way in the future)

Writing as above, there is a bad disadvantage, that is, the above method cannot be easily changed. Once the above code is compared based on age, everyone who calls compareTo() in the future will compare based on age. And if we need variables here, and we want to compare based on names, we must either change everything in the compareTo() method, or rewrite a method to compare based on names, and this is not the result we want to see.

Is there another way to solve this problem? The answer is yes, as follows:

2.Comparator

Comparator is called an external comparator because if we need to sort a certain class (for ease of understanding, we call this class class A here) (the class itself does not support sorting), we can define another Comparator that implements The class of the interface (class B) serves as the “comparator” of class A. This “comparator” only needs to implement the Comparator interface. In other words, we can create a new comparator by “implementing the Comparator class” and then sort the classes through this comparator.
Note: Class B is a class that implements the Comparator interface. It must implement the compare(To1, To2) method. This method contains our customized rules for comparing class A.

Examples are as follows:

import java.util.Comparator;

class Student{
    public String name;
    public int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

//Comparators
//Compare based on age
class AgeComparator implements Comparator<Student> {
    @Override
    public int compare(Student o1,Student o2) {
        return o1.age - o2.age;
    }
}
//Compare based on name
class NameComparator implements Comparator<Student>{
    @Override
    public int compare(Student o1, Student o2) {
//String compareTo method rewritten by yourself
        return o1.name.compareTo(o2.name);
    }
}
public class Test {
    public static void main(String[] args) {
        Student student1=new Student("chuichui",55);
        Student student2=new Student("wangdachui",96);


        //Usage of comparator
        AgeComparator ageComparator=new AgeComparator();
        System.out.println(ageComparator.compare(student1,student2));
        System.out.println("========================================== ===");
        NameComparator nameComparator=new NameComparator();
        System.out.println(nameComparator.compare(student1,student2));
    }
}






//This code has both age comparison and name comparison. It can be modified and is not in the class

(All negative numbers indicate that student1 is smaller than student2)

(This method achieves flexible comparison, we only need to pass in 2 objects to be compared)

As shown above, the Comparator<> interface is more flexible than the Comparable<> interface above.

Summary:

Both Comparable and Comparator can be used for comparison and sorting.
Comparable can be implemented directly in the class that needs to be sorted, overriding the compareTo(To) method; while Comparator requires another implementation class that implements the Comparator interface as a “comparator”. Both have their own advantages and disadvantages. Using Comparable is simpler. As long as the object that implements the Comparable interface directly becomes a comparable object, the source code needs to be modified. The advantage of using Comparator is that you do not need to modify the source code, but instead implement a comparator. When a custom object needs to be compared, you can pass the comparator and the object together to compare the size, and in the Comparator Users are strongly recommended to implement complex and universal logic by themselves so that it can match some simpler objects.

The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Java Skill TreeHomepageOverview 132112 people are learning the system