2016-12-07 30 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; 
      } 
     } 
    }; 

主に同じ日時の2つのイベントの場合は、日付でイベントを並べ替える必要があります開始イベントを最初に、終了イベントを最後に配置します。

あなたが同じgetTime()を有する二つのSleepDetailsのインスタンスを比較し、そのうちの一つがgetType() BEGINや他AWAKEを持っている場合、私はバグ

+0

'switch(arg0.getType())' - あなたは比較していません。 –

+0

ああ@ベネ何?同様の方法は間違いなくそれに従っています。 'Integer.compare(1,2)!= Integer.compare(2、1)'です。彼らは実際には、同じ、彼らは同じです。 – Rogue

+0

私の悪い、別の話 – Bene

答えて

5

をトリガーコレクションを持っていません。

compare (one, two) 

は与えるだろう-1 ​​

が0

を与えるだろう。これは契約違反

ながら:

実装者がそのSGNを確認する必要がありますが(比較します( x、y))== -sgn(すべてのxに対して(y、x)を比較する)とy。

arg0.getType()はBEGINもなく、ENDもされていない時はいつでも)また、あなたのcompare方法でarg1.getType()をチェックする必要があります。

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以外の型の列挙型の値が区別されないことです。特に、第1の型がBEGINでもENDでもないときは、第2の型にかかわらず、ゼロを返します。

ただし、この動作は対称的ではありません。ペアのBEGINとLIGHTの2つの項目を入れ替えると、-1と0が得られ、対称性が破られます。

BEGINとEND以外のすべての型を互いに等しく扱うことができますが、等値を決定するときは両側を使用する必要があります。

関連する問題