Heim  >  Artikel  >  Java  >  Detaillierte Erläuterung des Unterschieds zwischen Comparable- und Comparator-Schnittstellen in Java

Detaillierte Erläuterung des Unterschieds zwischen Comparable- und Comparator-Schnittstellen in Java

黄舟
黄舟Original
2017-09-07 10:15:231642Durchsuche

In diesem Artikel werden hauptsächlich die relevanten Informationen vorgestellt, die den Unterschied zwischen Comparable- und Comparator-Schnittstellen in Java erklären. Ich hoffe, dass Sie diesen Teil des Inhalts gründlich beherrschen können

Erläuterung von Java im Detail Der Unterschied zwischen Comparable- und Comparator-Schnittstellen in Java

In diesem Artikel wird der Unterschied zwischen Comparable- und Comparator-Schnittstellen in Java ausführlich analysiert. Beide verfügen über Vergleichsfunktionen Der Unterschied? Interessierte Java-Entwickler, lesen Sie weiter.

Comparable-Einführung

Comparable ist eine Sortierschnittstelle.

Wenn eine Klasse die Comparable-Schnittstelle implementiert, bedeutet dies „Diese Klasse unterstützt die Sortierung“. Da die Klasse, die die Comparable-Schnittstelle implementiert, das Sortieren unterstützt, kann die Liste (oder das Array) über Collections.sort (oder) verarbeitet werden, vorausgesetzt, es gibt nun eine „Liste (oder ein Array) von Objekten der Klasse, die die Comparable-Schnittstelle implementiert“. Arrays.sort) Sortieren.

Darüber hinaus können „Objekte von Klassen, die die Comparable-Schnittstelle implementieren“ als Schlüssel in „Ordered Maps (wie TreeMap)“ oder Elemente in „Ordered Sets (TreeSet)“ verwendet werden, ohne dass ein Vergleichsgerät angegeben werden muss.

Vergleichbare Definition

Die vergleichbare Schnittstelle enthält nur eine Funktion und ihre Definition lautet wie folgt:


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

Erklärung:

Angenommen, wir verwenden x.compareTo(y), um „die Größe von x und y zu vergleichen“. Wenn eine „negative Zahl“ zurückgegeben wird, bedeutet dies „x ist kleiner als y“; wenn „null“ zurückgegeben wird, bedeutet dies „x ist gleich y“; wenn eine „positive Zahl“ zurückgegeben wird, bedeutet dies „x ist“. größer als y".

Comparator-Einführung

Comparator ist eine Komparatorschnittstelle.

Wenn wir die Reihenfolge einer bestimmten Klasse steuern müssen und die Klasse selbst die Sortierung nicht unterstützt (d. h. sie implementiert die Comparable-Schnittstelle nicht), können wir einen „Komparator dieser Klasse“ erstellen " um die Sortierung durchzuführen. Dieser „Komparator“ muss nur die Komparatorschnittstelle implementieren.

Mit anderen Worten, wir können „die Comparator-Klasse implementieren, um einen neuen Komparator zu erstellen“ und dann die Klassen über diesen Komparator sortieren.

Comparator-Definition

Die Comparator-Schnittstelle enthält nur zwei Funktionen und ihre Definition lautet wie folgt:


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

Hinweis:

(01) Wenn eine Klasse die Comparator-Schnittstelle implementieren möchte: Sie muss die Funktion „compareTo(T o1, T o2)“ implementieren, muss jedoch nicht die Funktion „equals(Object obj)“ implementieren ) Funktion.

Warum nicht die Funktion equal(Object obj) implementieren? Weil jede Klasse standardmäßig equal(Object obj) implementiert hat. Alle Klassen in Java erben von java.lang.Object und die Funktion equal(Object obj) ist in Object.java implementiert. Daher sind alle anderen Klassen äquivalent zur Implementierung dieser Funktion.

(02) int Compare(T o1, T o2) ist „Vergleichen Sie die Größen von o1 und o2“. Die Rückgabe einer „negativen Zahl“ bedeutet „o1 ist kleiner als o2“; die Rückgabe von „Null“ bedeutet „o1 ist gleich o2“; die Rückgabe einer „positiven Zahl“ bedeutet „o1 ist größer als o2“.

Vergleich zwischen Comparator und Comparable

Comparable ist eine Sortierschnittstelle; wenn eine Klasse die Comparable-Schnittstelle implementiert, bedeutet dies „Diese Klasse unterstützt die Sortierung“.

Und Comparator ist ein Komparator. Wenn wir die Reihenfolge einer bestimmten Klasse steuern müssen, können wir einen „Komparator dieser Klasse“ zum Sortieren erstellen.

Wir können leicht feststellen, dass Comparable dem „internen Komparator“ und Comparator dem „externen Komparator“ entspricht.

Wir veranschaulichen diese beiden Schnittstellen durch ein Testprogramm. Der Quellcode lautet wie folgt:


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();
    }
  }
}

Dieses Programm wird unten erklärt.

a) Personenklassendefinition. Wie folgt:


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;
  }  
}

Erklärung:

(01) Die Person-Klasse repräsentiert eine Person. Es gibt zwei Attribute in der Person-Klasse: Alter und Name „Name einer Person“.
(02) Die Person-Klasse implementiert die Comparable-Schnittstelle, sodass sie sortiert werden kann.

b) In main() haben wir das Array „Person’s List“ (Liste) erstellt. Wie folgt:


// 新建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) Als nächstes drucken wir alle Elemente der Liste aus. Wie folgt:


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

d) Dann sortieren wir die Liste mit der Funktion sort() von Collections.

Da Person die Comparable-Schnittstelle implementiert, wird beim Sortieren über sort () nach der von Person unterstützten Sortiermethode sortiert, dh nach den durch CompareTo (Person Person) definierten Regeln. Wie folgt:


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

e) Vergleich von Comparable und Comparator

Wir definieren zwei Komparatoren, AscAgeComparator und DescAgeComparator, um das Aufsteigen bzw. Summieren von Person durchzuführen . Nach unten sortieren.

e.1) AscAgeComparator

Es sortiert Personen in aufsteigender Reihenfolge nach Alter. Der Code lautet wie folgt:


/**
 * @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

Es sortiert Personen in absteigender Reihenfolge nach Alter. Der Code lautet wie folgt:


/**
 * @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) Ergebnisse ausführen

Führen Sie das Programm aus und die Ausgabe ist wie folgt:


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

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des Unterschieds zwischen Comparable- und Comparator-Schnittstellen in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn