Java foundation of Comparable & Comparator

I. Overview

This article is for comparing two Java interfaces sort of brief Comparator and Comparable use, and then will come to explain their respective sub-use by way of example, first we take a look at related presentations Comparable interface.


Two, Comparable Interface

First conclusion : Comparable in Chinese means "comparable", that is, a class that implements this interface is sortable .

For example, we customize a simple Student category:

public class Student {
    
    private int score;   // 学生成绩
    
    private String name; // 学生名字

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

Suppose we now need to score a class of students from low to high sort, when two students score the same name is sorted according to the order, as follows:

100 zhangsan
Lisi 60
wangwu 80
Marck 80

The four students after sorting, the output should be as follows:

60 Lisi
Marck 80
wangwu 80
zhangsan 100

You can see the results are sorted in order from low to high, and the results are due marck wangwu and 80 points, so continue to compare their names, since the beginning of the letter marck "m" "w" is smaller than wangwu initials, so marck ahead of the wangwu.

So, how should we define this sort of way? The answer is to make the Student class implement the Comparable interface. Let's first see how this interface is defined as:

public interface Comparable<T> {
    int compareTo(T o);
}

We can see this interface defines only one compareTo()method, suppose we compare x and y by x.compareTo (y) size, then:

  • If the method returns negative, indicating that x is smaller than Y;
  • If the method returns to zero, indicating that x and Y are equal;
  • If the method returns a positive number, x is larger than described y.

So we can transform the Student class as follows:

public class Student implements Comparable<Student>{

    private int score;

    private String name;

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

    @Override
    public int compareTo(Student s) {
        // 调用方式假设为 x.compareTo(y) 的形式
        // x.score > y.score,返回1
        if (this.score > s.score){
            return 1;
        } else if (this.score < s.score){  // x.score < y.score,返回 -1
            return -1;
        } else {
            // x.score = y.score 时进一步比较 name 的大小排序
            return this.name.compareTo(s.name);
        }
    }
    
    @Override
    public String toString() {
        return this.name + "  " + this.score;
    }

    public static void main(String[] args) {
        Student[] students = new Student[4];
        students[0] = new Student(100, "zhangsan");
        students[1] = new Student(60, "lisi");
        students[2] = new Student(80, "wangwu");
        students[3] = new Student(80, "marck");
        Arrays.sort(students);
        for (Student s : students){
            System.out.println(s);
        }
    }
}

Student class can be seen from the above transformation, compareTo()the method first compares the size of the performance, larger than a direct return 0, less than 0 -1 directly. If the scores are equal, it will further compare the two Student object name, because the name is of type String, and String has long for us to realize Comparable interface, so we call it direct compareTo()method to return.

In the main method we make it a simple test, by Arrays.sort()sorting the array of students method, output results are as follows:

60 Lisi
Marck 80
wangwu 80
zhangsan 100

And you can see our results are consistent with expectations.

Note: Whether the array is sorted Arrays.sort () method is used to sort the Collections.sort List () method, which are in ascending order of the sorted array, the order of the compareTo () returns the value of the method is determined .

For understanding this passage above, we come to understand through an example: for student achievement rankings, from low to high exhaust does not meet our habits, we are accustomed to from high in the end row, then we should be how to top Student category further amend it?

Actually very simple, we just want Arrays.sort()a method that a large number of results is relatively "small" on the line, because this method is sorted in the order of arrival of childhood, the modified compareTo()method is as follows:

@Override
public int compareTo(Student s) {
    // 调用方式假设为 x.compareTo(y) 的形式
    // x.score < y.score,返回1
    if (this.score < s.score){
        return 1;
    } else if (this.score > s.score){  // x.score > y.score,返回 -1
        return -1;
    } else {
        // x.score = y.score 时进一步比较 name 的大小排序
        return this.name.compareTo(s.name);
    }
}

It can be seen that in fact, the two cases is greater than the return value of less than do the swap, after modifying the output results are as follows:

100 zhangsan
Marck 80
wangwu 80
Lisi 60

We can see the output results, according to results from high in the end sort, but the name is still in smallest to largest order.

Comparable interface summarize:

  • Class that implements the interface means that may be ordered.
  • compareTo() Is the case of the method defines how the comparison of the two objects, the return value is greater than, less than, equal to 0 are represented by the caller is greater than, equal to, less than process parameters.

Three, Comparator interfaces

Comparator translated into a comparator, which means it is a similar tool for comparison. We revisit the original Student category:

public class Student {
    
    private int score;   // 学生成绩
    
    private String name; // 学生名字

    public Student(int score, String name) {
        this.score = score;
        this.name = name;
    }
    
    public int getScore() {
        return score;
    }

    public String getName() {
        return name;
    }
}

In order to become Student sortable class, let us realize Comparable interface, while achieving a compareTo()method to determine the size relationship is defined in this method. This is achieved within a class comparable effect.

But if we do not take into account in the design category for its implement the Comparable interface, but now we need to sort these objects, then we can consider the use of comparator Comparator, which is equivalent to a comparable tool in our class Compare the size of the relationship between objects externally defined, first of all we see its definition:

public interface Comparator<T> {
    int compare(T o1, T o2);

    boolean equals(Object o);
}

You can see Comparator defines two interface methods, which we have to realize that compare()method, equals()the method may not be implemented, because all classes inherit from Object, and Object provides default equals()methods. Next, to see the key compare () method, it can be seen that there are two parameters o1 and o2, its return value is defined as follows:

  • If the return value is greater than zero, indicating o1> o2;
  • If the return value is less than zero, indicating o1 <o2;
  • If the return value is zero, indicating o1 = o2.

Next we define a Student class comparator to compare the Student aid:

public class StudentComparator implements Comparator<Student> {
    @Override
    public int compare(Student s1, Student s2) {
        if (s1.getScore() < s2.getScore()) {
            return 1;
        } else if (s1.getScore() > s2.getScore()){
            return -1;
        } else {
            return s1.getName().compareTo(s2.getName());
        }
    }
}

Here we still follow scores in descending order, from small to reach the same result name sort ordering to be defined.

Note that the comparator is compared in the outer class-based, so we have for private fields corresponding getter so we add their values. Next we see its use (note the example below Student class does not implement the Comparable interface):

public class Test {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>(4);
        students.add(new Student(100, "zhangsan"));
        students.add(new Student(60, "lisi"));
        students.add(new Student(80, "wangwu"));
        students.add(new Student(80, "marck"));
        Collections.sort(students, new StudentComparator());
        for (Student s : students){
            System.out.println(s);
        }
    }
}

Here we are in the form of student List of storage of data, and then to sort them by calling Collections.sort () method. The output is shown below:

100 zhangsan
Marck 80
wangwu 80
Lisi 60

We can see that we can achieve the same effect by ordering Comparator. Next we take another example, the priority queue PriorityQueue changed from the default minimum heap max heap form.

PriorityQueue a constructor can be passed comparator Comparator, as follows:

public PriorityQueue(Comparator<? super E> comparator);

This construction method for comparing the size of the incoming relationship element defines the priority queue, and the default implementation is minimal PriorityQueue priority queue, then we change my thinking, will reverse the magnitude relationship, you can achieve maximum heap, the code is as follows below:

public static void main(String[] args) {
    PriorityQueue<String> maxHeap = new PriorityQueue<String>(new Comparator<String>() {
        @Override
        public int compare(String s1, String s2) {
            return s2.compareTo(s1);
        }
    });
}

Here we are with String types of elements, for example, in the definition of a comparator, we direct return s2.compareTo(s1)will be able to achieve the maximum stack effect.


IV Summary

For links and differences Comparable and Comparator summarized as follows:

  • Comparable and Comparator interfaces are defined compare relevant interface.
  • Comparable interface used in the class "internal" class that implements the interface is expressed as sortable.
  • Comparator interface used in the class of "external", did not implement the Comparable interface for the class, we can compare them by providing a comparator to the class.

Guess you like

Origin blog.csdn.net/qq_38182125/article/details/93849185