Maison  >  Article  >  Java  >  Explication détaillée de la différence entre les interfaces Comparable et Comparator en Java

Explication détaillée de la différence entre les interfaces Comparable et Comparator en Java

黄舟
黄舟original
2017-09-07 10:15:231697parcourir

Cet article présente principalement les informations pertinentes qui expliquent la différence entre les interfaces Comparable et Comparator en Java. J'espère que grâce à cet article, vous pourrez maîtriser en profondeur cette partie du contenu. Les amis dans le besoin pourront se référer à

. Explication de Java en détail La différence entre les interfaces Comparable et Comparator en Java

Cet article analysera en détail la différence entre les interfaces Comparable et Comparator en Java. Les deux ont des fonctions de comparaison, alors qu'est-ce que c'est. la différence ? Développeurs Java intéressés, continuez à lire.

Introduction à Comparable

Comparable est une interface de tri.

Si une classe implémente l'interface Comparable, cela signifie "cette classe prend en charge le tri". Étant donné que la classe qui implémente l'interface Comparable prend en charge le tri, en supposant qu'il existe désormais une "Liste (ou tableau) d'objets de la classe qui implémente l'interface Comparable", la Liste (ou le tableau) peut être traitée via Collections.sort (ou Arrays.sort) Trier.

De plus, les « objets des classes qui implémentent l'interface Comparable » peuvent être utilisés comme clés dans les « Cartes ordonnées (telles que TreeMap) » ou comme éléments dans les « Ensembles ordonnés (TreeSet) » sans spécifier de périphérique de comparaison.

Définition Comparable

L'interface Comparable ne comprend qu'une seule fonction, et sa définition est la suivante :


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

Explication :

Supposons que nous utilisions x.compareTo(y) pour "comparer la taille de x et y". Si un « nombre négatif » est renvoyé, cela signifie « x est inférieur à y » ; si « zéro » est renvoyé, cela signifie « x est égal à y » ; si un « nombre positif » est renvoyé, cela signifie « x est supérieur à y ». y".

Introduction au comparateur

Comparator est une interface de comparaison.

Si nous devons contrôler l'ordre d'une certaine classe et que la classe elle-même ne prend pas en charge le tri (c'est-à-dire qu'elle n'implémente pas l'interface Comparable, alors nous pouvons créer un "comparateur de cette classe) ; " pour effectuer le tri. Ce "comparateur" n'a besoin que d'implémenter l'interface Comparator.

En d'autres termes, nous pouvons "implémenter la classe Comparator pour créer un nouveau comparateur" puis trier les classes via ce comparateur.

Définition du Comparateur

L'interface du Comparateur ne comprend que deux fonctions, et sa définition est la suivante :


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

Remarque :

(01) Si une classe souhaite implémenter l'interface Comparator : elle doit implémenter la fonction compareTo(T o1, T o2), mais elle n'a pas besoin d'implémenter la fonction equals(Object obj ) fonction.

Pourquoi ne pas implémenter la fonction equals(Object obj) ? Parce que n'importe quelle classe a implémenté equals(Object obj) par défaut. Toutes les classes de Java héritent de java.lang.Object, et la fonction equals(Object obj) est implémentée dans Object.java, par conséquent, toutes les autres classes sont équivalentes à l'implémentation de cette fonction ;

(02) int compare(T o1, T o2) est "Comparez les tailles de o1 et o2". Renvoyer un « nombre négatif » signifie « o1 est inférieur à o2 » ; renvoyer « zéro » signifie « o1 est égal à o2 » ; renvoyer un « nombre positif » signifie « o1 est supérieur à o2 ».

Comparaison entre Comparator et Comparable

Comparable est une interface de tri ; si une classe implémente l'interface Comparable, cela signifie "cette classe prend en charge le tri".

Et Comparator est un comparateur ; si nous avons besoin de contrôler l'ordre d'une certaine classe, nous pouvons créer un "comparateur de cette classe" pour le tri.

On peut facilement constater que Comparable est équivalent à "comparateur interne", et Comparator est équivalent à "comparateur externe".

Nous illustrons ces deux interfaces à travers un programme de test. Le code source est le suivant :


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

Ce programme est expliqué ci-dessous.

a) Définition de la classe de personne. Comme suit :


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

Explication :

(01) La classe Person représente une personne. Il y a deux attributs dans la classe Person : l'âge et. nom "nom de la personne".
(02) La classe Person implémente l'interface Comparable, elle peut donc être triée.

b) Dans main(), nous avons créé le tableau Person’s List (liste). Comme suit :


// 新建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) Ensuite, nous imprimons tous les éléments de la liste. Comme suit :


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

d) Ensuite, nous trions la liste via la fonction sort() de Collections.

Puisque Person implémente l'interface Comparable, lors du tri via sort(), il sera trié selon la méthode de tri prise en charge par Person, c'est-à-dire les règles définies par compareTo(Person person). Comme suit :


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

e) Comparaison de Comparable et Comparator

Nous définissons deux comparateurs, AscAgeComparator et DescAgeComparator, pour effectuer respectivement l'ascendant et la sommation de Person . Faites le tri.

e.1) AscAgeComparator

Il trie les personnes par ordre croissant d'âge. Le code est le suivant :


/**
 * @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) Comparateur DescAgeComparator

Il trie les Personnes par ordre décroissant d'âge. Le code est le suivant :


/**
 * @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) Résultats d'exécution

Exécutez le programme et le résultat est le suivant :


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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn