> Java > java지도 시간 > Java의 Comparable 인터페이스와 Comparator 인터페이스의 차이점에 대한 자세한 설명

Java의 Comparable 인터페이스와 Comparator 인터페이스의 차이점에 대한 자세한 설명

黄舟
풀어 주다: 2017-09-07 10:15:23
원래의
1729명이 탐색했습니다.

이 글은 주로 Java의 Comparable 인터페이스와 Comparator 인터페이스의 차이점을 자세히 설명하는 관련 정보를 소개합니다. 이 글을 통해 이 부분을 완전히 익힐 수 있기를 바랍니다. Java의 Comparable 인터페이스와 Comparator 인터페이스의 차이점을 자세히 설명하세요

이 기사에서는 Java의 Comparable 인터페이스와 Comparator 인터페이스의 차이점을 자세히 분석합니다. 둘 다 비교 기능이 있으므로 관심 있는 Java 개발자는 계속해서 읽어야 합니다. .

Comparable 소개

Comparable은 정렬 인터페이스입니다.

클래스가 Comparable 인터페이스를 구현하는 경우 "이 클래스는 정렬을 지원합니다"를 의미합니다. Comparable 인터페이스를 구현하는 클래스는 정렬을 지원하므로 이제 "Comparable 인터페이스를 구현하는 클래스의 객체 목록(또는 배열)"이 있다고 가정하면 해당 목록(또는 배열)은 Collections.sort(또는 Arrays.sort) 정렬.

또한 "Comparable 인터페이스를 구현하는 클래스의 객체"는 비교기를 지정하지 않고도 "Ordered Maps(예: TreeMap)"의 키 또는 "Ordered Set(TreeSet)"의 요소로 사용할 수 있습니다.

Comparable 정의

Comparable 인터페이스에는 하나의 함수만 포함되며 그 정의는 다음과 같습니다.

package java.lang;
import java.util.*;
public interface Comparable<T> {
  public int compareTo(T o);
}
로그인 후 복사

설명:

"x와 y의 크기를 비교"하기 위해 x.compareTo(y)를 사용한다고 가정합니다. . "음수"가 반환되면 "x가 y보다 작습니다"를 의미하고 "0"이 반환되면 "x가 y와 같습니다"를 의미합니다. y보다 크다".

Comparator 소개

Comparator는 비교기 인터페이스입니다.

특정 클래스의 순서를 제어해야 하고 클래스 자체가 정렬을 지원하지 않는 경우(즉, Comparable 인터페이스를 구현하지 않음) 정렬을 수행하기 위해 "이 클래스의 비교기"를 만들 수 있습니다. . 이 "비교기"는 Comparator 인터페이스만 구현하면 됩니다.

즉, "Comparator 클래스를 구현하여 새 비교기를 생성"한 다음 이 비교기를 통해 클래스를 정렬할 수 있습니다.

Comparator 정의

Comparator 인터페이스에는 두 개의 함수만 포함되며 해당 정의는 다음과 같습니다.

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보다 작다"는 것을 의미하고, "0"을 반환한다는 것은 "o1이 o2와 같다"는 것을 의미하고, "양수"를 반환한다는 것은 "o1이 o2보다 크다"는 것을 의미합니다.

Comparator 및 Comparable

Comparable은 정렬 인터페이스입니다. 클래스가 Comparable 인터페이스를 구현하는 경우 "이 클래스는 정렬을 지원합니다"를 의미합니다.

비교기는 비교기입니다. 특정 클래스의 순서를 제어해야 하는 경우 정렬을 위해 "이 클래스의 비교기"를 만들 수 있습니다.

우리는 다음을 쉽게 찾을 수 있습니다: Comparable은 "내부 비교기"와 동일하고 Comparator는 "외부 비교기"와 동일합니다.

테스트 프로그램을 통해 이 두 가지 인터페이스를 설명합니다. 소스코드는 다음과 같습니다.

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) Person 클래스 정의. 다음과 같습니다:

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 클래스에는 age와 name이라는 두 가지 속성이 있습니다.

(02) Person 클래스는 Comparable 인터페이스를 구현하므로 정렬이 가능합니다.

b) main()에서는 Person의 목록 배열(목록)을 생성합니다. 다음과 같습니다:

// 新建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) 그런 다음 Collections의 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) Comparing Comparable과 Comparator

Person을 각각 오름차순과 내림차순으로 정렬하기 위해 AscAgeComparator와 DescAgeComparator라는 두 개의 비교기를 정의합니다.

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 comparator

Person을 연령별로 내림차순으로 정렬합니다. 코드는 다음과 같습니다.

/**
 * @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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿