2014-12-06 80 views
1

一切似乎都運行良好(幾天),但我碰到一個問題只有一次,並有一個非常困難的時間來重現問題。 「Java 7 - 「比較方法違反其總合約!」

」比較方法違反其總合同!「被拋出,完全讓我措手不及。我有以下幾點:

public class CustomComparator implements Comparator<Chromosome> { 

public int compare(Chromosome c1, Chromosome c2){ 

    return c1.compareTo(c2); 
} 

} 

我的染色體類:

public class Chromosome implements Comparable<Chromosome>{ 

private double rank; 

//bunch of methods... 

@Override public int compareTo(Chromosome c){ 

    final int BEFORE = -1; 
    final int EQUAL = 0; 
    final int AFTER = 1; 

    if (this.getRank() == c.getRank()) //getRank() simply returns a double value 'rank' 
     return EQUAL; 

    else if (this.getRank() < c.getRank()) 
      return BEFORE; 

    else //i.e. (this.getRank() > c.getRank()) 
     return AFTER; 

} 

我有一個ArrayList和我同時使用Collections.sort(MYLIST)和Collections.sort(MYLIST,Collections.reverseOrder()) 。到目前爲止他們仍然工作得很好。我只在100次運行中遇到過這種錯誤。這個實現有什麼問題嗎?

+1

是否有任何雙值的NaN? – 2014-12-06 13:29:00

+0

可能是'0.0/0.0'或類似的結果。 – 2014-12-06 13:30:31

+2

你的compareTo方法可以簡單地說,'return Double.compare(this.rank,c.rank);'。自定義比較器自從它在染色體實例上調用'compareTo'時就沒用了。 – 2014-12-06 13:31:06

回答

3

Java 7已經改變了他們的排序算法的行爲。如果檢測到違反compareTo方法的一般合同,他們現在會拋出異常。您可以閱讀關於該合同的屬性,例如here

一般來說它可以被侵犯,例如在的情況下,這將解決一個< B和B <一個。如果這是在Java 7之前檢測到的,那麼它就會被默默地忽略。現在將拋出一個異常。

如果你想使用舊的行爲,您可以使用以下方法:

System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");

但我不鼓勵你這樣做。您只需通過Double.compare(a, b)將您的實現更改爲雙比較的標準實現。此實現正確處理雙精度的無窮大和NaN值。

此外,如果您的Comparator只是代表compareTo方法,它通常可以被丟棄。

+0

謝謝。我只是使用Double.compare()來代替。我沒有再次遇到這個問題,所以這很奇怪。 另外,我不確定我是否理解違反合同的例子。我怎麼能有兩個雙值a和b,使得a wFateem 2014-12-07 16:43:18

+1

@wFateem這只是一個如何被違犯的例子。實際上還有其他幾條規則必須遵循。例如對稱之一。 a == a應該總是如此。但是定義雙打如何工作的IEEE 754標準指出Double.NaN應該是!= Double.NaN,這違背了對稱規則。這是Double.compare(...)修復的問題之一。 – noone 2014-12-07 17:53:31

+0

非常感謝您的澄清。欣賞它 – wFateem 2014-12-08 13:24:04

2

可能是你的一個參數可能是由於正或負無窮,即被零除。也不要在double值上依賴==。您應該只使用:

return Double.compare(this.getRank(), c.getRank()); 
+0

感謝您使用Double.compare()的提示,而不是使用它。 它不能成爲零除的問題。 Rank是基於圖像像素值(int在0和255之間)的神經網絡返回的值。神經網絡使用S形函數。 – wFateem 2014-12-07 16:40:03

+0

很高興幫助。請接受答案來關閉此問題,以便可以幫助其他人解決類似問題。 – SMA 2014-12-07 16:41:29

相關問題