Comparable versus Comparator in Java

  • 2020-04-01 02:20:08
  • OfStack

Introduction of Comparable,
Comparable is the sort interface.
If a class implements the Comparable interface, it means that "the class supports sorting."   Even if the class that implements the Comparable interface supports sorting, suppose that there is now a "List List (or array) of objects of the class that implements the Comparable interface," then the List List (or array) can be sorted through collections.sort (or arrays.sort).
In addition, "object of a class that implements the Comparable interface" can be used as a key in an ordered map (such as TreeMap) or an element in an ordered collection (TreeSet) without specifying a comparator.
Comparable to define
The Comparable interface consists of only one function, which is defined as follows:

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

Description:
Suppose we use x.compareTo(y) to "compare the size of x and y". If you return a negative number, it means that x is less than y. Return zero, which means "x is equal to y"; Returns "positive", meaning "x is greater than y".
Introduction of Comparator
The Comparator is the Comparator interface.
If we need to control the order of a class that does not support sorting (that is, the Comparable interface is not implemented); Then we can set up a "comparator for this class" to sort. The Comparator only needs to implement the Comparator interface.
That is, we can "implement the Comparator class to create a new Comparator" and then sort the classes through the Comparator.
Comparator definition
The Comparator interface consists of only two functions, which are defined as follows:

package java.util;
public interface Comparator<T> {
    int compare(T o1, T o2);
    boolean equals(Object obj);
}

Description:
If a class wants to implement the Comparator interface, it must implement the compareTo(T o1, T o2) function, but it can not implement the equals(Object obj) function.
              Why not implement the equals(Object obj) function? Because the default for any class is to already implement equals(Object obj). All classes in Java are inherited from java.lang.object, and the equals(Object obj) function is implemented in object.java. Therefore, all other classes implement this function.
Int compare(T o1, T o2) is "compare the size of o1 and o2". Return "negative", meaning "o1 is less than o2"; To return "zero" means "o1 is equal to o2"; Returns "positive", meaning "o1 is greater than o2".
Comparator is Comparable
Comparable is the sort interface; If a class implements the Comparable interface, it means that "the class supports sorting."
The Comparator is the Comparator; If we need to control the order of a class, we can set up a "comparator of that class" to sort it.
It's not hard to see that Comparable is equivalent to an "internal Comparator" and Comparator is equivalent to an "external Comparator."
We use a test program to illustrate the two interfaces. Source as follows:

import java.util.*;
import java.lang.Comparable;

public class CompareComparatorAndComparableTest{
    public static void main(String[] args) {
        //New ArrayList(dynamic array)
        ArrayList<Person> list = new ArrayList<Person>();
        //Add objects to the ArrayList
        list.add(new Person("ccc", 20));
        list.add(new Person("AAA", 30));
        list.add(new Person("bbb", 10));
        list.add(new Person("ddd", 40));
        //Print the original sequence of the list
        System.out.printf("Original  sort, list:%sn", list);
        //Sort the list
        //It's going to look like "Person implemented Comparable<String> "Interface" sorts, that is, sorts by "name"
        Collections.sort(list);
        System.out.printf("Name      sort, list:%sn", list);
        //The list is sorted by an AscAgeComparator
        //The AscAgeComparator is sorted in ascending order of "age"
        Collections.sort(list, new AscAgeComparator());
        System.out.printf("Asc(age)  sort, list:%sn", list);
        //List is sorted by DescAgeComparator
        //DescAgeComparator is sorted in descending order of "age"
        Collections.sort(list, new DescAgeComparator());
        System.out.printf("Desc(age) sort, list:%sn", list);
        //Determine if two persons are equal
        testEquals();
    }
    
    private static void testEquals() {
        Person p1 = new Person("eee", 100);
        Person p2 = new Person("eee", 100);
        if (p1.equals(p2)) {
            System.out.printf("%s EQUAL %sn", p1, p2);
        } else {
            System.out.printf("%s NOT EQUAL %sn", p1, p2);
        }
    }
    
    private static class Person implements Comparable<Person>{
        int age;
        String name;
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public int getAge() {
            return age;
        }
        public String toString() {
            return name + " - " +age;
        }
        
        boolean equals(Person person) {
            if (this.age == person.age && this.name == person.name)
                return true;
            return false;
        }
        
        @Override
        public int compareTo(Person person) {
            return name.compareTo(person.name);
            //return this.name - person.name;
        }
    }
    
    private static class AscAgeComparator implements Comparator<Person> {
        @Override 
        public int compare(Person p1, Person p2) {
            return p1.getAge() - p2.getAge();
        }
    }
    
    private static class DescAgeComparator implements Comparator<Person> {
        @Override 
        public int compare(Person p1, Person p2) {
            return p2.getAge() - p1.getAge();
        }
    }
}

This procedure is described below.
A) Person class definition. As follows:

private static class Person implements Comparable<Person>{
    int age;
    String name;
        ...
    
    @Override
    public int compareTo(Person person) {
        return name.compareTo(person.name);
        //return this.name - person.name;
    }   
}

Description:
The Person class represents a Person, and the Persong class has two attributes: age and name.
(02) the Person class implements the Comparable interface, so it can be sorted.
B) in main(), we create a List array of persons. As follows:

//New ArrayList(dynamic array)
ArrayList<Person> list = new ArrayList<Person>();
//Add objects to the ArrayList
list.add(new Person("ccc", 20));
list.add(new Person("AAA", 30));
list.add(new Person("bbb", 10));
list.add(new Person("ddd", 40));

C) next, we print out all the elements of the list. As follows:

//Print the original sequence of the list
System.out.printf("Original sort, list:%sn", list);

D) then we sort the list through the Collections sort() function.
      Because Person implements the Comparable interface, when you sort through sort(), you sort by the rules defined by the sort that Person supports, compareTo(Person Person). As follows:

//Sort the list
//It's going to look like "Person implemented Comparable<String> "Interface" sorts, that is, sorts by "name"
Collections.sort(list);
System.out.printf("Name sort, list:%sn", list);

E) compare Comparable with Comparator
      We define two comparators, AscAgeComparator and DescAgeComparator, to sort the Person in ascending and descending order, respectively.
E.1) AscAgeComparator comparator
It's sort Person in ascending order by age. The code is as follows:


private static class AscAgeComparator implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person p2) {
        return p1.getAge() - p2.getAge();
    }
}

E.2) DescAgeComparator comparator
It's sort Person in descending order by age. The code is as follows:


private static class DescAgeComparator implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person p2) {
        return p2.getAge() - p1.getAge();
    }
}

F) running results
Run the program and the output is as follows:

Original  sort, list:[ccc - 20, AAA - 30, bbb - 10, ddd - 40]
Name      sort, list:[AAA - 30, bbb - 10, ccc - 20, ddd - 40]
Asc(age)  sort, list:[bbb - 10, ccc - 20, AAA - 30, ddd - 40]
Desc(age) sort, list:[ddd - 40, AAA - 30, ccc - 20, bbb - 10]
eee - 100 EQUAL eee - 100

Related articles: