簡體   English   中英

Java中的比較器和可比較實現

[英]comparator and comparable implementation in java

我知道這些接口用於集合中的排序對象。 但是,我懷疑它們之間的真正區別。 當您想將兩個對象與當前對象(本)進行比較時,我讀到的一個事實是使用可比性。

但是我的問題是,即使使用比較器,我們也可以比較相同的對象類型。

這里真的有什么區別。 我很困惑。 假設以下示例,

class Person implements Comparable<Person> {
  private String firstName;
  private String lastName;
  private int age;

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  public String getLastName() {
    return lastName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  public int compareTo(Person anotherPerson){     
    int anotherPersonAge =anotherPerson.getAge();  
    return this.age - anotherPersonAge;    
  }
}

如果我使用比較器,我將擁有一個實現比較器的類,而不是this.age,它具有person.age。 那么,這里有什么不同?

public class LastNameComparator implements Comparator<Person> {
  public int compare(Person person, Person anotherPerson) {
    int age1 = person.getAge();
    int age2 = anotherPerson.getAge();

     return age1 - age2; 
  }
}

我不知道內部邏輯Collections.sort的使用。 如果是這樣,請說明以上幾點。

我也相信沒有必要返回-1,1或0。 上面的實現也有效吧? 我遇到的一個問題是,如果我們返回1,則列表如何根據升序或降序對項目進行排序? 我認為其差異要考慮並根據差異進行排序。

考慮可比文件

該接口對實現該接口的每個類的對象強加了總體排序。 此排序稱為類的自然排序,而該類的compareTo方法被稱為其自然比較方法。

比較器

比較功能,對某些對象集合施加總體排序。 可以將比較器傳遞給排序方法(例如Collections.sort或Arrays.sort),以精確控制排序順序。 比較器還可以用於控制某些數據結構(例如排序集或排序映射)的順序,或為沒有自然順序的對象集合提供排序。

Comparable對象可以通過與另一個對象進行比較來確定其順序(自然順序),而Comparator是知道如何比較兩個對象並確定其特定順序的對象。 這里的區別在於誰負責比較。

自然排序通過compareTo強制使用已定義的順序,但是如果您想更改該順序,或者更糟的是,沒有已定義的比較邏輯怎么辦? 這是Comparator派上用場的地方,因為您可以基於不同的比較來對集合進行排序,這些比較可以通過發出新的Comparator器來動態切換,而不是一些討厭的邏輯,您應該告訴Comparable對象“嘿,現在您按名稱排序而不是年齡”。

關於比較結果之間的差異,對每個對象進行檢查。 例如,采取三人隨着年齡的101520 1510比較時返回-1 ,與20比較時返回-1 ,定義了三個人的順序。

選擇適合您需求的方法。 如果您的比較邏輯是穩定的並且以后不會更改,則您可能希望擁有Comparable對象,但是如果需要根據不同的條件對集合進行排序,則應該使用Comparator

快速掃描java.util.Collections javadocs提供了以下內容:

public static void sort(List list)-根據指定元素的自然順序將指定列表升序排序。 列表中的所有元素必須實現Comparable接口 此外,列表中的所有元素必須相互可比較(也就是說,對於列表中的任何元素e1和e2,e1.compareTo(e2)均不得拋出ClassCastException)。

public static void sort(List list,Comparator c)-根據指定比較器所誘導的順序對指定列表進行排序。 列表中的所有元素都必須使用指定的比較器進行相互比較 (即c.compare(e1,e2)不得對列表中的任何元素e1和e2拋出ClassCastException。

可以推斷出sort(List list)然后使用Comparable接口, sort(List list, Comparator c)使用比較器。

要回答您的最后一個問題,以您描述的方式使用這兩種方法沒有什么區別。擁有這兩種方法的目的是使您能夠以不同的方式比較對象,而不是以不同的方式使用不同的實現。

以這種方式考慮...您擁有具有一個整數的Class IntegerWrapper ,並且在該類中實現了Comparable 因此,當使用Collection.sort對它們進行排序時...它會為您提供升序的對象...

但是當您想更改此順序並希望降序時 ,則必須實現比較器以按所需順序對其進行排序...

在Java中,類型永遠只能實現一次接口,也就是說,您不能說

public class Foo implements Comparable<Foo>, Comparable<String> {}

這意味着Foo的實例將始終以某種方式進行排序-您不能使排序在某種情況下的行為與另一種情況的行為不同。

Comparator ,在另一方面,是獨立可排序的實例。 單個類型可以具有多個Comparator (與完全相同的Comparable相對)。 如果您需要某種排序,只需創建一個新的Comparator

編寫Comparator對不同類型的實例進行排序也很容易-使用Comparable很難做到這一點,因為所有涉及的實例都必須彼此了解:任何實例都可以將其他實例作為compareTo()參數,並且實現一些通用接口等

當有人使用Comparable接口時,我總是會感到害怕,因為它幾乎總是錯誤的選擇。 可比用於定義自然順序,而不用於排序。 Java知道必須滿足的equals-hashcode合同。 大多數開發人員都知道。 但是還有另外一個重要的合同:可比合同。

這意味着:

a.equals(b)<==> a.compareTo(b)== 0

在您的示例中,您不能在一個TreeSet中擁有兩個具有相同年齡的不同人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM