Home  >  Article  >  Java  >  Detailed explanation of the difference between Comparable and Comparator interfaces in Java

Detailed explanation of the difference between Comparable and Comparator interfaces in Java

黄舟
黄舟Original
2017-09-07 10:15:231699browse

This article mainly introduces the relevant information that explains the difference between Comparable and Comparator interfaces in Java. I hope that through this article you can thoroughly master this part of the content. Friends in need can refer to

Detailed explanation of Java The difference between the Comparable and Comparator interfaces in Java

This article will analyze in detail the difference between the Comparable and Comparator interfaces in Java. Both have comparative functions, so what is the difference? Interested Java Developers, keep reading.

Comparable Introduction

Comparable is a sorting interface.

If a class implements the Comparable interface, it means "this class supports sorting". Since the class that implements the Comparable interface supports sorting, assuming that there is now a "List (or array) of objects of the class that implements the Comparable interface", the List (or array) can be processed through Collections.sort (or Arrays.sort) Sort.

In addition, "objects of classes that implement the Comparable interface" can be used as keys in "ordered maps (such as TreeMap)" or elements in "ordered sets (TreeSet)" without specifying comparisons. device.

Comparable definition

The Comparable interface only includes one function, and its definition is as follows:


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

Explanation :

Suppose we use x.compareTo(y) to "compare the size of x and y". If "negative number" is returned, it means "x is smaller than y"; if "zero" is returned, it means "x is equal to y"; if "positive number" is returned, it means "x is greater than y".

Comparator Introduction

Comparator is a comparator interface.

If we need to control the order of a certain class, and the class itself does not support sorting (that is, it does not implement the Comparable interface); then, we can create a "comparator of this class" to perform sorting. 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.

Comparator definition

The Comparator interface only includes two functions, and its definition is as follows:


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

Description:

(01) If a class wants to implement the Comparator interface: it must implement the compareTo(T o1, T o2) function, but it does not need to implement the equals(Object obj) function.

Why not implement the equals(Object obj) function? Because any class has implemented equals(Object obj) by default. All classes in Java inherit from java.lang.Object, and the equals(Object obj) function is implemented in Object.java; therefore, all other classes are equivalent to implementing this function.

(02) int compare(T o1, T o2) is "compare the sizes of o1 and o2". Returning "negative number" means "o1 is smaller than o2"; returning "zero" means "o1 is equal to o2"; returning "positive number" means "o1 is greater than o2".

Comparing Comparator and Comparable

Comparable is a sorting interface; if a class implements the Comparable interface, it means "this class supports sorting".

The Comparator is a comparator; if we need to control the order of a certain class, we can create a "comparator of this class" for sorting.

It is not difficult for us to find that Comparable is equivalent to "internal comparator", and Comparator is equivalent to "external comparator".

We illustrate these two interfaces through a test program. The source code is as follows:


import java.util.*;
import java.lang.Comparable;
/**
 * @desc "Comparator"和“Comparable”的比较程序。
 *  (01) "Comparable"
 *  它是一个排序接口,只包含一个函数compareTo()。
 *  一个类实现了Comparable接口,就意味着“该类本身支持排序”,它可以直接通过Arrays.sort() 或 Collections.sort()进行排序。
 *  (02) "Comparator"
 *  它是一个比较器接口,包括两个函数:compare() 和 equals()。
 *  一个类实现了Comparator接口,那么它就是一个“比较器”。其它的类,可以根据该比较器去排序。
 *
 *  综上所述:Comparable是内部比较器,而Comparator是外部比较器。
 *  一个类本身实现了Comparable比较器,就意味着它本身支持排序;若它本身没实现Comparable,也可以通过外部比较器Comparator进行排序。
 */
public class CompareComparatorAndComparableTest{
  public static void main(String[] args) {
    // 新建ArrayList(动态数组)
    ArrayList<Person> list = new ArrayList<Person>();
    // 添加对象到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));
    // 打印list的原始序列
    System.out.printf("Original sort, list:%s\n", list);
    // 对list进行排序
    // 这里会根据“Person实现的Comparable<String>接口”进行排序,即会根据“name”进行排序
    Collections.sort(list);
    System.out.printf("Name   sort, list:%s\n", list);
    // 通过“比较器(AscAgeComparator)”,对list进行排序
    // AscAgeComparator的排序方式是:根据“age”的升序排序
    Collections.sort(list, new AscAgeComparator());
    System.out.printf("Asc(age) sort, list:%s\n", list);
    // 通过“比较器(DescAgeComparator)”,对list进行排序
    // DescAgeComparator的排序方式是:根据“age”的降序排序
    Collections.sort(list, new DescAgeComparator());
    System.out.printf("Desc(age) sort, list:%s\n", list);
    // 判断两个person是否相等
    testEquals();
  }
  /**
   * @desc 测试两个Person比较是否相等。
   *  由于Person实现了equals()函数:若两person的age、name都相等,则认为这两个person相等。
   *  所以,这里的p1和p2相等。
   *
   *  TODO:若去掉Person中的equals()函数,则p1不等于p2
   */
  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 %s\n", p1, p2);
    } else {
      System.out.printf("%s NOT EQUAL %s\n", p1, p2);
    }
  }
  /**
   * @desc Person类。
   *    Person实现了Comparable接口,这意味着Person本身支持排序
   */
  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;
    }
    /**
     * 比较两个Person是否相等:若它们的name和age都相等,则认为它们相等
     */
    boolean equals(Person person) {
      if (this.age == person.age && this.name == person.name)
        return true;
      return false;
    }
    /**
     * @desc 实现 “Comparable<String>” 的接口,即重写compareTo<T t>函数。
     * 这里是通过“person的名字”进行比较的
     */
    @Override
    public int compareTo(Person person) {
      return name.compareTo(person.name);
      //return this.name - person.name;
    }
  }
  /**
   * @desc AscAgeComparator比较器
   *    它是“Person的age的升序比较器”
   */
  private static class AscAgeComparator implements Comparator<Person> {
    @Override 
    public int compare(Person p1, Person p2) {
      return p1.getAge() - p2.getAge();
    }
  }
  /**
   * @desc DescAgeComparator比较器
   *    它是“Person的age的升序比较器”
   */
  private static class DescAgeComparator implements Comparator<Person> {
    @Override 
    public int compare(Person p1, Person p2) {
      return p2.getAge() - p1.getAge();
    }
  }
}

This program is explained below.

a) Person class definition. As follows:


private static class Person implements Comparable<Person>{
  int age;
  String name;
    ...
  /** 
   * @desc 实现 “Comparable<String>” 的接口,即重写compareTo<T t>函数。
   * 这里是通过“person的名字”进行比较的
   */
  @Override
  public int compareTo(Person person) {
    return name.compareTo(person.name);
    //return this.name - person.name;
  }  
}

Explanation:

(01) The Person class represents a person. There are two attributes in the Person class: age (age) and name" person's name".
(02) The Person class implements the Comparable interface, so it can be sorted.

b) In main(), we created a List array (list) of Person. As follows:


// 新建ArrayList(动态数组)
ArrayList<Person> list = new ArrayList<Person>();
// 添加对象到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 elements of the list. As follows:


// 打印list的原始序列
System.out.printf("Original sort, list:%s\n", list);

d) Then, we sort the list through the sort() function of Collections.

Since Person implements the Comparable interface, when sorting through sort(), it will be sorted according to the sorting method supported by Person, that is, the rules defined by compareTo(Person person). As follows:


// 对list进行排序
// 这里会根据“Person实现的Comparable<String>接口”进行排序,即会根据“name”进行排序
Collections.sort(list);
System.out.printf("Name sort, list:%s\n", list);

e) Comparing Comparable and Comparator

We define two comparators, AscAgeComparator and DescAgeComparator, to sort Person in ascending and descending order respectively. .

e.1) AscAgeComparator

It sorts Person in ascending order according to age. The code is as follows:


/**
 * @desc AscAgeComparator比较器
 *    它是“Person的age的升序比较器”
 */
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 sorts Person in descending order by age. The code is as follows:


/**
 * @desc DescAgeComparator比较器
 *    它是“Person的age的升序比较器”
 */
private static class DescAgeComparator implements Comparator<Person> {
  @Override
  public int compare(Person p1, Person p2) {
    return p2.getAge() - p1.getAge();
  }
}

f) Running result

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

The above is the detailed content of Detailed explanation of the difference between Comparable and Comparator interfaces in Java. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn