2016-06-28 81 views
2

我知道這似乎是一個微不足道的問題(我毫不懷疑所有'聰明人'會來標記它爲重複),但我沒有找到足夠的解釋我的問題。難道這讓我很難理解這個簡單的主題嗎?如何在實現「可比較」時定義排序順序?

我理解其背後Comparable接口以及它是如何工作的基礎知識,但我有一個真正的困難已瞭解如何確定的排序ORDER

例如 - 我有一個非常簡單的Fruit類:

public class Fruit implements Comparable<Fruit> { 
private String fruitName; 
private String fruitDesc; 
private int quantity; 

public Fruit(String fruitName, String fruitDesc, int quantity) { 
    this.fruitName = fruitName; 
    this.fruitDesc = fruitDesc; 
    this.quantity = quantity; 
} 

public String getFruitName() { 
    return fruitName; 
} 
public void setFruitName(String fruitName) { 
    this.fruitName = fruitName; 
} 
public String getFruitDesc() { 
    return fruitDesc; 
} 
public void setFruitDesc(String fruitDesc) { 
    this.fruitDesc = fruitDesc; 
} 
public int getQuantity() { 
    return quantity; 
} 
public void setQuantity(int quantity) { 
    this.quantity = quantity; 
} 

public int compareTo(Fruit compareFruit) { 
    //ascending order 
    return this.quantity - ((Fruit) compareFruit).getQuantity(); 
} 

爲什麼聲明compareTo像上面會按升序進行排序,並在聲明它的時候正好相反:

return ((Fruit) compareFruit).getQuantity() - this.quantity; 

它將按降序排列?

+0

你是什麼意思,「你怎麼確定他們之間?」?你的意思是如何訂購相同數量的水果?這基本上取決於所使用的排序算法。但是你不應該對這些元素的順序做任何假設,因爲它可能會被忽視。如果您依賴一個確切而穩定的訂單,則需要確保您的班級的所有屬性都是按排序順序考慮的。 – dpr

+0

不知道我是否正確理解你的問題 - 排序順序只是由'compareTo'返回的整數符號決定的。順便說一下,不要通過getter和直接屬性訪問混合訪問屬性。 –

+0

當您交換認爲大於或小於的順序時,您將從升序切換到降序。 –

回答

2

Javadoc

比較與指定對象此對象爲順序。返回 負整數,零或正整數,因爲此對象比指定對象的 小,等於或大於此值。實現者 必須爲所有x和 確保sgn(x.compareTo(y))== -sgn(y.compareTo(x))。 (這意味着則x.compareTo(Y)當且僅當 y.compareTo(X)拋出異常必須拋出異常。)

實現類還必須確保關係是可傳遞: (則x.compareTo(Y) > 0 & & y.compareTo(z)> 0)意味着x.compareTo(z)> 0。

最後,對於所有z,實現者必須確保x.compareTo(y)== 0意味着 sgn(x.compareTo(z))== sgn(y.compareTo(z))。

強烈建議,但不是嚴格要求 (x.compareTo(y)== 0)==(x.equals(y))。一般而言,任何實現了Comparable接口並且違反 條件的類 都應該清楚地表明這一事實。推薦的語言是「注: 這個類的自然排序與equals不一致。」

在前面的描述中,符號sgn(表達式)指定數學符號函數,該函數被定義爲根據表達式的值是負數,零還是正數來返回 -1,0或1中的一個。

1

sort方法按其定義按升序進行排序。

根據 的元素自然排序將指定列表按升序排序。

compareTo方法是就在你的第一例子中,錯誤的在第二,根據:

比較與指定對象此對象爲順序。返回 負整數,零或正整數,因爲此對象比指定對象的 小,等於或大於此值。

+0

爲什麼它錯了?我檢查了它,它工作完美。 那麼,當我在對象之間進行交換時,返回的(int)號碼現在相反,所以位置順序? – Nimrod

+0

@Nimrod,這是錯誤的,因爲它不尊重來自「Comparable」的方法定義的合同。如果您需要反向排序,請使用其他方式,例如'Collections.reverseOrder()':https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#reverseOrder()。 – Berger

+0

對不起,但我仍然不明白.. 'Collections'與列表相關,而我想使用一個數組。你能舉一個例子還是更具體? – Nimrod

0

從我的理解,如果方法返回一個負值(值小於0),第一個對象出現在排序列表中的第二個對象之前。如果它返回一個正值(值大於0),則第一個對象位於排序列表中的第二個對象之後。如果它返回0,那麼這兩個對象是相等的。

第一個對象是指您的示例中由this關鍵字引用的對象,第二個對象是指傳入compareTo方法的對象。

0

從Java API:

比較與指定對象這個對象的順序。返回負整數,零或正整數,因爲此對象小於,等於或大於指定的對象。

鏈接:https://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html

compareTo()方法返回一個整數,它告訴分揀機實例之間的相對位置,使得if (a.compareTo(b) > 0),然後a被認爲是「大」,因此應該出現在排序的列表b後。同樣if (a.compareTo(b) < 0)a被認爲是「較小」。

因此,如果你想按升序排列,你應該compareTo()執行引用thiscompareObject之前,即this.value - compareObject.value;

堅持簡而言之: a.compareTo(b) > 0基本意思是「一個大於b」。同樣a.compareTo(b) < 0意味着「a小於b」。

0

compareTo方法確定而不是確定排序操作的順序(升序與降序)。

定義排序操作的代碼確定順序。排序操作會重複調用compareTo,對於要排序的集合中的每個對象至少調用一次。排序操作的其餘代碼如何跟蹤調用compareTo代碼的結果,確定結果是升序還是降序。例如,Collections.sort排序操作總是按升序排序。該庫中的代碼將調用每個對象的方法compateTo