Comparable, Compparator and java Sorting and Comparing

Posted by foxtrotwhiskey on Thu, 06 Jun 2019 19:58:21 +0200

1: The concepts of comparison and ranking

Compare: Compare the two entity classes by >, =, <

Sort: In a collection class, sort the entities in the collection class. The sorting algorithm is based on the comparison function provided by the entity class.

Basic types provide default comparison algorithms, such as string providing alphabetical comparisons and int providing integer comparisons.

 

2: Comparable and Comparator

but in the world of software development, any code-free heap concept is a hooligan. So no matter how perfect our explanation is, we must show me the code.

Let's start with a code like this:

public class CollectorTest {
    public static void main(String[] args) {

        ArrayList<Student> students = new ArrayList<>();
        students.add(new Student("a", 3));
        students.add(new Student("c", 2));
        students.add(new Student("b", 1));
        students.add(new Student("d", 4));
        for (Student student : students) {
            System.out.printf("name:%s, age: %d \n", student.name, student.age);
        }
    }
}

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

 

But now we need to traverse by age. What should we do? This is when the sort interface comes into play. The sorted interface Comparable can be provided for Student as follows.

public class CollectorTest {
    public static void main(String[] args) {

        ArrayList<Student> students = new ArrayList<>();
        students.add(new Student("a", 3));
        students.add(new Student("c", 2));
        students.add(new Student("b", 1));
        students.add(new Student("d", 4));
        Collections.sort(students);
        for (Student student : students) {
            System.out.printf("name:%s, age: %d \n", student.name, student.age);
        }
    }
}

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

    @Override
    public int compareTo(Object o) {
        Student student = (Student)o;
        if (age> student.age)
        {
            return 1;
        }
        else if (age == student.age)
        {
            return 0;
        }
        else
        {
            return -1;
        }
        //return Integer.valueOf(age).compareTo(Integer.valueOf(student.age));
    }
}

The output is as follows:

name:b, age: 1
name:c, age: 2
name:a, age: 3
name:d, age: 4

Excellent. PS: Note the last commented line in the sorting method. The logic in the sorting method can be replaced by this line. I just used the Integer compareTo method during the demonstration.

Now the question arises. I don't want to sort by age. I want to sort by name. What should I do? To know that we can only implement a sorting interface, sorting interface has only one method. At this time, the comparator will come into use!

We implement a name comparator as follows:

public class CollectorTest {
    public static void main(String[] args) {

        ArrayList<Student> students = new ArrayList<>();
        students.add(new Student("a", 3));
        students.add(new Student("c", 2));
        students.add(new Student("b", 1));
        students.add(new Student("d", 4));
        //Collections.sort(students);
        students.sort(new NameSorter());
        for (Student student : students) {
            System.out.printf("name:%s, age: %d \n", student.name, student.age);
        }
    }
}

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

    @Override
    public int compareTo(Object o) {
        Student student = (Student)o;
        if (age> student.age)
        {
            return 1;
        }
        else if (age == student.age)
        {
            return 0;
        }
        else
        {
            return -1;
        }
        //return Integer.valueOf(age).compareTo(Integer.valueOf(student.age));
    }
}

class NameSorter implements Comparator{

    @Override
    public int compare(Object o1, Object o2) {
        Student s1 =(Student) o1;
        Student s2 =(Student) o2;
        return s1.name.compareTo(s2.name);
    }
}

As a result:

name:a, age: 3
name:b, age: 1
name:c, age: 2
name:d, age: 4

In the future, we need to rank students according to their gender and grades, and there may be more and more requirements for ranking, so we need to implement more comparators.

 

3: Comparable and Comparator generic version Comparable < T > and Comparator < T >

If we have a little experience, we will find that the interface between Comparable and Compparator of the above code is no longer recommended. When generics come out, it is recommended that all non-generic collection classes and interfaces should not be used as much as possible. As for the reason, we can see a little bit from the above code.

Note the comparison function, such as:

Student s1 =(Student) o1;
Student s2 =(Student) o2;

We found that the function was packed and unpacked. This can affect performance. If we have tens of thousands of complex entity objects in our collection, the performance consumed in sorting is objective. The emergence of generics can avoid disassembly and packing.

Therefore, we should realize Comparable < T > and Comparable < T >. The final code is as follows:

package com.zuikc.se.collectors;

/**
* Sorting and Comparator Usage, Comparable and Comparator, and java Sorting and Comparing
* author:Most Courses (zuikc.com)
*/
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class CollectorTest {
    public static void main(String[] args) {

        ArrayList<Student> students = new ArrayList<>();
        students.add(new Student("a", 3));
        students.add(new Student("c", 2));
        students.add(new Student("b", 1));
        students.add(new Student("d", 4));
        //Collections.sort(students);
        students.sort(new NameSorter());
        for (Student student : students) {
            System.out.printf("name:%s, age: %d \n", student.name, student.age);
        }
    }
}

class Student implements Comparable<Student>{
    public String name;
    public int age;
    public Student(String name, int age){
        this.name = name;
        this.age = age;
    }

    @Override
    public int compareTo(Student student) {
        if (age> student.age)
        {
            return 1;
        }
        else if (age == student.age)
        {
            return 0;
        }
        else
        {
            return -1;
        }
        //return Integer.valueOf(age).compareTo(Integer.valueOf(student.age));
    }
}

class NameSorter implements Comparator<Student>{

    @Override
    public int compare(Student s1, Student s2) {
        return s1.name.compareTo(s2.name);
    }
}

Topics: Java