ホームページ Java &#&チュートリアル Java の Comparable インターフェイスと Comparator インターフェイスの違いの詳細な説明

Java の Comparable インターフェイスと Comparator インターフェイスの違いの詳細な説明

Sep 07, 2017 am 10:15 AM
comparable comparator java

この記事では、Java の Comparable インターフェイスと Comparator インターフェイスの違いを詳しく説明する関連情報を中心に紹介します。この部分を必要とする友人は、この記事を参照してください。 Java の Comparable インターフェイスと Comparator インターフェイスの違いを詳しく説明します

この記事では、Java の Comparable インターフェイスと Comparator インターフェイスの違いを詳しく分析します。興味のある Java 開発者は、その違いを読み続けてください。 。

Comparable の概要

Comparable は並べ替えインターフェイスです。

クラスが Comparable インターフェースを実装している場合、それは「このクラスは並べ替えをサポートしている」ことを意味します。 Comparable インターフェイスを実装するクラスは並べ替えをサポートしているため、「Comparable インターフェイスを実装するクラスのオブジェクトのリスト (または配列)」があると仮定すると、そのリスト (または配列) は Collections.sort (またはArrays.sort) 並べ替えます。

また、「Comparableインターフェースを実装したクラスのオブジェクト」は、コンパレータを指定せずに「順序付きマップ(TreeMapなど)」のキーや「順序付きセット(TreeSet)」の要素として使用できます。

比較可能な定義

比較可能なインターフェースには関数が 1 つだけ含まれており、その定義は次のとおりです:

package java.lang;
import java.util.*;
public interface Comparable<T> {
  public int compareTo(T o);
}
ログイン後にコピー

説明:

「x と y のサイズを比較する」ために x.compareTo(y) を使用するとします。 。 「負の数」が返された場合は「x が y より小さい」ことを意味し、「ゼロ」が返された場合は「x が y に等しい」ことを意味し、「正の数」が返された場合は「x が y に等しい」ことを意味します。 y より大きい」。

Comparator の概要

Comparator はコンパレータ インターフェイスです。

特定のクラスの順序を制御する必要があり、クラス自体が並べ替えをサポートしていない場合 (つまり、Comparable インターフェイスを実装していない場合)、並べ替えを実行するために「このクラスのコンパレーター」を作成できます。 。この「コンパレータ」は Comparator インターフェイスを実装するだけで済みます。

言い換えれば、「Comparator クラスを実装して新しいコンパレータを作成」し、このコンパレータを通じてクラスを並べ替えることができます。

Comparator 定義

Comparator インターフェイスには 2 つの関数のみが含まれており、その定義は次のとおりです:

package java.util;
public interface Comparator<T> {
  int compare(T o1, T o2);
  boolean equals(Object obj);
}
ログイン後にコピー

説明:

(01) クラスが Comparator インターフェイスを実装したい場合: クラスは CompareTo( T を実装する必要があります) o1, To o2) 関数を使用しますが、equals(Object obj) 関数を実装する必要はありません。

equals(Object obj) 関数を実装してみてはいかがでしょうか? なぜなら、どのクラスもデフォルトでequals(Object obj)を実装しているからです。 Java のすべてのクラスは java.lang.Object を継承しており、equals(Object obj) 関数は Object.java に実装されているため、他のすべてのクラスはこの関数を実装することと同等です。

(02) int Compare(T o1, T o2) は「o1 と o2 の大きさを比較する」です。 「負の数」を返すと「o1 は o2 より小さい」ことを意味し、「ゼロ」を返すと「o1 は o2 に等しい」を意味し、「正の数」を返すと「o1 は o2 より大きい」ことを意味します。

Comparator と Comparable

Comparable は並べ替えインターフェイスです。クラスが Comparable インターフェイスを実装している場合、それは「このクラスは並べ替えをサポートしている」ことを意味します。

Comparator はコンパレータです。特定のクラスの順序を制御する必要がある場合は、並べ替え用の「このクラスのコンパレータ」を作成できます。

次のことが簡単にわかります。 Comparable は「内部コンパレータ」と同等であり、Comparator は「外部コンパレータ」と同等です。

これら 2 つのインターフェイスをテスト プログラムを通じて説明します。ソースコードは以下の通りです:

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();
    }
  }
}
ログイン後にコピー

このプログラムについては以下で説明します。

a) 人物クラスの定義。以下のように:

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;
  }  
}
ログイン後にコピー

説明:

(01) Person クラスには、年齢と名前という 2 つの属性があります。

(02) PersonクラスはComparableインターフェースを実装しているのでソート可能です。

b) main()で、人のList配列(リスト)を作成します。以下のように:

// 新建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) 次に、リストのすべての要素を出力します。次のように:

// 打印list的原始序列
System.out.printf("Original sort, list:%s\n", list);
ログイン後にコピー

d) 次に、コレクションの sort() 関数を使用してリストを並べ替えます。

personはComparableインターフェースを実装しているため、sort()でソートする際は、personがサポートしているソート方法、つまりcompareTo(person person)で定義されたルールに従ってソートされます。以下の通り:

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

e) Comparable と Comparator の比較

2 つのコンパレータ、AscAgeComparator と DescAgeComparator を定義して、それぞれ Person を昇順と降順に並べ替えます。

e.1) AscAgeComparator

人物を年齢の昇順に並べ替えます。コードは次のとおりです:

/**
 * @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 コンパレータ

パーソンを年齢の降順に並べ替えます。コードは次のとおりです:

/**
 * @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) 実行結果

プログラムを実行すると、出力は次のようになります:

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
ログイン後にコピー

以上がJava の Comparable インターフェイスと Comparator インターフェイスの違いの詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Javaの平方根 Javaの平方根 Aug 30, 2024 pm 04:26 PM

Java の平方根のガイド。ここでは、Java で平方根がどのように機能するかを、例とそのコード実装をそれぞれ示して説明します。

Javaの完全数 Javaの完全数 Aug 30, 2024 pm 04:28 PM

Java における完全数のガイド。ここでは、定義、Java で完全数を確認する方法、コード実装の例について説明します。

Java の乱数ジェネレーター Java の乱数ジェネレーター Aug 30, 2024 pm 04:27 PM

Java の乱数ジェネレーターのガイド。ここでは、Java の関数について例を挙げて説明し、2 つの異なるジェネレーターについて例を挙げて説明します。

ジャワのウェカ ジャワのウェカ Aug 30, 2024 pm 04:28 PM

Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

Javaのスミス番号 Javaのスミス番号 Aug 30, 2024 pm 04:28 PM

Java のスミス番号のガイド。ここでは定義、Java でスミス番号を確認する方法について説明します。コード実装の例。

Java Springのインタビューの質問 Java Springのインタビューの質問 Aug 30, 2024 pm 04:29 PM

この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

Java 8 Stream Foreachから休憩または戻ってきますか? Java 8 Stream Foreachから休憩または戻ってきますか? Feb 07, 2025 pm 12:09 PM

Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです

Java での日付までのタイムスタンプ Java での日付までのタイムスタンプ Aug 30, 2024 pm 04:28 PM

Java での日付までのタイムスタンプに関するガイド。ここでは、Java でタイムスタンプを日付に変換する方法とその概要について、例とともに説明します。

See all articles