[Java] in depth understanding of Comparable interface and Comparator interface | you can use it for sorting

Keywords: Java

Reference: Java language programming (Advanced) -- written by Mr. Liang Yong and translated by Mr. Dai Kaiyu

Operating environment

  • Windows10
  • JDK8
  • IDAE

1, Foreword

In the Java language, if you want to judge the size of two variables, you may think of it first

if(a > b){
	// ...
}

However, this has great limitations. For example, two variables of String type cannot be compared directly with > < for example

The application with the largest comparison size is the sorting between arrays

For example, the static sort method in the java.uti.Collections class is used to sort the array list

public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList(Arrays.asList(4,3,6,8));
        Collections.sort(list);
        System.out.println(list);
}

Operation results

[3, 4, 6, 8]

As we all know, Java is an object-oriented programming language, which means that we not only sort the array list of Integer type in the above example, but also other types, such as String, Character, or other classes. In practical applications, such as comparing the grades, height and weight of all students in a class.

JDK8 provides two interfaces: java.lang.Comparable and java.util.Comparator

It is specially used to solve the problem of comparing two objects. At the same time, they are applied to the sorting function in various native classes.

2, Summary

In the JDK native API, many classes implement the Comparable interface, such as the most basic reference types Integer, String, Date, etc. among them, all basic types of digital wrapper classes implement this interface.

The only method defined in the Comparable interface: compareTo(T o) is used to compare two elements of the same class that implements the Comparable interface.

Java. Util. Comparator < T > interface, which implements the comparison between classes that do not implement the Comparable interface,

3, Comparable

The Comparable interface is used in the java.lang package to implement the comparison between the interface implementation classes

The source code of Comparable.java without comments is as follows:

package java.lang;
import java.util.*;
public interface Comparable<T> {
    public int compareTo(T o);
}

Meaning of returned value of compareTo(T o) method:

Return valuemeaning
0The current object and the passed in formal parameter o comparison result are equal
1The current object is larger than the passed in formal parameter o comparison result
-1The current object is smaller than the incoming formal parameter o comparison result

In ascending order, - 1 is returned when the current object < parameter

In descending order, when the current object < parameter, 1 is returned

The interface only declares a compareTo method, which means that its implementation class must override this method

Where < T > is a generic representation method, which represents the type of comparison. Through this symbol, the parameter types passed in the method can be specified

For example, declare a comparable custom class Student:

class Student implements Comparable<Student>{
	private double score;
	@Override
	public int compareTo(Student o){
		//...
	}	
	// getScore & setScore
}

The compareTo() method compares the current object with the incoming formal parameter o, and the comparison logic can be customized.

3.1 complete the sorting of student classes by implementing the Comparable interface

Tested student class Student.java

class Student implements Comparable<Student>{

    private String name;
    private double score;
    private double height;

    public Student(String name, double score, double height) {
        this.name = name;
        this.score =score;
        this.height=height;
    }
    public double getScore(){
        return score;
    }
    public double getHeight(){
        return height;
    }
    @Override
    public int compareTo(Student o) {
        if(this.score < o.getScore())
            return -1;
        else if(this.score > o.getScore())
            return 1;
        else
            return 0;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", score=" + score +
                ", height=" + height +
                '}';
    }
}

Main class of Demo.java test

class Demo {
    public static void main(String[] args) {
        ArrayList<Student> all = new ArrayList<>();
        all.add(new Student("Da Xiong", 0, 140));
        all.add(new Student("Dora A dream",100 ,129));
        all.add(new Student("Jingxiang",95 ,143));
        Collections.sort(all);
        for (Student student : all) {
            System.out.println(student);
        }
    }
}

3.1.1 ranking by grades

Modify Student.java as follows:

Ascending order

    @Override
    public int compareTo(Student o) {
        if(this.score < o.getScore())
            return -1;
        else if(this.score > o.getScore())
            return 1;
        else
            return 0;
    }

Descending order

    @Override
    public int compareTo(Student o) {
        if(this.score < o.getScore())
            return 1;
        else if(this.score > o.getScore())
            return -1;
        else
            return 0;
    }

Test run results in ascending order

Student{name = 'Daxiong', score=0.0, height=140.0}
Student{name = 'Jingxiang', score=95.0, height=143.0}
Student{name = 'Doraemon', score=100.0, height=129.0}

3.1.2 ranking by height

Ascending order

    @Override
    public int compareTo(Student o) {
        if(this.height < o.getHeight())
            return -1;
        else if(this.height > o.getHeight())
            return 1;
        else
            return 0;
    }

Descending order

    @Override
    public int compareTo(Student o) {
        if(this.height < o.getHeight())
            return 1;
        else if(this.height > o.getHeight())
            return -1;
        else
            return 0;
    }

Test run results in ascending order

Student{name = 'Jingxiang', score=95.0, height=143.0}
Student{name = 'Daxiong', score=0.0, height=140.0}
Student{name = 'Doraemon', score=100.0, height=129.0}

3.1.3 summary Comparable

To sum up, using this interface only needs to rewrite the compareTo(T o) method, and the method returns three results - 1, 0 and 1. The size of the current object and the formal parameter object are compared in the method.

4, Comparator comparator

The Comparator interface is in the java.util package. It is used to compare classes that do not implement the java.lang.comparable interface

The java.io.Serializable interface is implemented in the comparator interface to mark that the class is serializable.

The source code of the interface is as follows:

package java.util;

import java.io.Serializable;
import java.util.function.Function;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import java.util.function.ToDoubleFunction;
import java.util.Comparators;
public interface Comparator<T> {//...}

All methods of Comparator interface

In the figure below, except for the method with arrow, other methods are implemented in the interface.

It can be seen that the implementation class of the Comparator interface also needs to override the compare() method.

However, unlike the compare() method in the Comparable interface, the former needs to pass in two parameters, while the latter only needs to pass in one parameter.

4.1 sorting through Comparator comparator

Unlike before, the interface is implemented by another class, not the class to compare.

Student entity class

class Student{

    private String name;
    private double score;
    private double height;

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", score=" + score +
                ", height=" + height +
                '}';
    }
}

scoreComparator is used exclusively for the Student object's grade comparator class

class scoreComparator implements Comparator<Student>{

    @Override
    public int compare(Student o1, Student o2) {
        if(o1.getScore() > o2.getScore())
            return 1;
        else if(o1.getScore() < o2.getScore())
            return -1;
        else
            return 0;
    }
}

Demo.java implements the main class of sorting

class Demo {
   public static void main(String[] args) {
       ArrayList<Student> all = new ArrayList<>();
       all.add(new Student("Da Xiong", 0, 140));
       all.add(new Student("Dora A dream",100 ,129));
       all.add(new Student("Jingxiang",95 ,143));
       all.sort(new scoreComparator());
       System.out.println(all);
   }
}

Operation results:

[Student{name ='daxiong ', score=0.0, height=140.0}, Student{name ='jingxiang', score=95.0, height=143.0}, Student{name ='doraemon ', score=100.0, height=129.0}]

4.2 method of compiling object comparison size

With the scorecomparator object, you can easily compare the scores of student classes. The implementation is as follows:

public Student max(Student o1, Student o2, scoreComparator c){
      if(c.compare(o1, o2) > 0)
          return o1;
      else
          return o2;
}

Compared with the previous Comparable interface

Obviously, if you want to compare students with different logic, such as height or grades, you need different comparators.

The former rewrites the comparaTo method in the student class, and the comparison can only be made through the logic in the method

The latter can define more implementation classes of Comparator interface to represent different comparison reference objects

5, Summary

  • j a v a . l a n g . C o m p a r a b l e java.lang.Comparable java.lang.Comparable for comparison C o m p a r a b l e Comparable Object of the Comparable class

use C o m p a r a b l e Comparable Comparing elements of the Comparable interface is called comparing using natural sorting

  • j a v a . u t i l . C o m p a r a t o r java.util.Comparator java.util.Comparator is used to compare non implemented C o m p a r a b l e Comparable Object of the Comparable class

use C o m p a r a t o r Comparator Comparator interface comparison is called comparison using comparator

C o m p a r a b l e Comparable Comparable C o m p r a t o r Comprator Comprator
The implementation class is the comparison classThe implementation class is any other class
compareTo() method in comparison classThe compareTo() method can be placed in any class
Declare only compareTo methodsProvides many methods of comparison

Posted by MikeSnead on Sun, 21 Nov 2021 16:37:34 -0800