2016-12-07 64 views
1

我已經讀過關於傳遞比較器的所有線程,我不明白爲什麼這個比較函數違反規則。如果有人可以清理自己的眼睛,這是很簡單的,我認爲,但我不能讓它比較一般合同違規

堆棧是:(簡體)

java.util.TimSort.mergeLo(TimSort.java:747) 
java.util.TimSort.mergeAt(TimSort.java:483) 
java.util.TimSort.mergeCollapse(TimSort.java:410) 

我的對象

public class SleepDetails { 
    private DateTime time; 
    private SleepEnum type; 
    [...] 
} 

public enum SleepEnum { 
    DEEP(0), LIGHT(1), AWAKE(2), BEGIN(16), END(17); 
    [...] 
} 

比較靜態成類

Comparator<SleepDetails> comparator = new Comparator<SleepDetails>(){ 
     public int compare(SleepDetails arg0, SleepDetails arg1) { 
      int res = arg0.getTime().compareTo(arg1.getTime()); 
      if (res != 0) 
       return res; 
      if (arg0.getType() == arg1.getType()) 
       return 0; 
      switch(arg0.getType()) { 
       case BEGIN: 
       return -1; 
       case END: 
       return 1; 
       default: 
       return 0; 
      } 
     } 
    }; 

主要我想按日期排序事件,如果兩個事件具有相同的日期時間作爲最後的開始事件和結束事件。

我沒有收集觸發的bug

+0

'switch(arg0.getType())' - 你沒有比較。 –

+0

呃@Bene什麼?類似的方法絕對不會遵循這一點。 'Integer.compare(1,2)!= Integer.compare(2,1)'。實際上,它們只是相匹配。 – Rogue

+0

我的壞,不同的故事 – Bene

回答

5

如果你比較具有相同getTime() 2個SleepDetails實例,其中一人有getType() BEGIN和其他醒來。

compare (one, two) 

會給-1

​​

會給0

這違反了合同:

實現程序必須確保SGN(比較( x,y))== -sgn(比較(y,x))和y。

您還必須檢查arg1.getType()compare方法(當arg0.getType()既不BEGIN也不END)。

public int compare(SleepDetails arg0, SleepDetails arg1) { 
     int res = arg0.getTime().compareTo(arg1.getTime()); 
     if (res != 0) 
      return res; 
     if (arg0.getType() == arg1.getType()) 
      return 0; 
     switch(arg0.getType()) { 
      case BEGIN: 
      return -1; 
      case END: 
      return 1; 
      default: 
      switch(arg1.getType()) { 
       case BEGIN: 
       return 1; 
       case END: 
       return -1; 
       default: 
       return 0; 
      } 
     } 
    } 
+0

好的,謝謝晶瑩剔透 –

1

問題是您的代碼不區分BEGIN和END以外類型的枚舉值。特別是,當第一個類型既不是BEGIN也不是END時,它將返回零,而不管第二種類型。

但是,這種行爲是不對稱的:如果你交換一對BEGIN和LIGHT中的兩個項目,你會得到-1和0,打破了對稱性。

您可以將除BEGIN和END之外的所有其他類型視爲彼此相等,但在決定相等性時您需要使用雙方。

相關問題