2012-02-28 11 views
20

Java 7でJavaコードをコンパイルして実行した後、「比較メソッドがその一般契約に違反しています。比較メソッドがJava 7の一般契約に違反しています

私はComparison method violates its general contract! Java 7 onlyを読んでおり、以前のバージョンのJavaでは無視されていたコードに問題があることを認識しています。しかし、私は自分のコードに何が間違っているかは分からない。 Collections.sort()はエラーを生成します。

私のコードは次のとおりです。

public Comparator sortBySmoothDays() { 
    Comparator c = new Comparator() { 
     public int compare(Object arg0, Object arg1) { 
      Date date0 = ((PosObject)arg0).getDate(); 
      Date date1 = ((PosObject)arg1).getDate(); 

      double d1 = MyUtils.calcSmoothDays(date0, new Date()); 
      double d2 = MyUtils.calcSmoothDays(date1, new Date()); 
      if (d1 >= d2) { 
       return 1; 
      } 
      else { 
       return -1; 
      } 
     } 
    }; 
    return c; 
} 


Comparator c = ComparatorUtils.getInstance().sortBySmoothDays(); 
Collections.sort(posList, c); 

誰でも助けることができますか?ありがとうございました!

+0

JFI:この例外をスローすると、新しいJava7機能で正しくdouble値を比較する最も簡単な方法は、Double.compareを呼び出すことです。古い動作は、新しいシステムプロパティで設定できます。java.util.Arrays.useLegacyMergeSort参照:http://stackoverflow.com/a/8417446/450812 – alfonx

答えて

31

コンパレータが0を返さなければならないことを意味します。現在の実装では、等しい場合は1を返します。

double d1 = MyUtils.calcSmoothDays(date0, new Date()); 
double d2 = MyUtils.calcSmoothDays(date1, new Date()); 

return Double.compare(d1, d2); 
+0

ありがとうございました! – gordon613

+0

-1ではなく、1を返します。 – xehpuk

+0

@xehpukそうです。それを私が直した。 –

19

コンパレータでは、すべてのオブジェクトがそれ自身よりも大きく比較されます。は常に1を返します。

これは以下requirementに違反:

実装は、すべてのxおよびyについて((Y、X)を比較されたい)== -sgn((x、y)を比較されたい)そのSGNを保証しなければなりません。

上記の要件は、がゼロを返す必要があることを意味します。

私はcontractを読んで、実装がそれを実現することをお勧めします。

特に、date0.equals(date1)の場合、コンパレータは浮動小数点の変換や比較を行うことなく、直ちにゼロを返すはずです。

+0

さらに一般的には、このメソッドを使用して2つのオブジェクトが等しくなることはありません。 0(または等しい)結果をもたらすコードパスはありません。 –

+0

ありがとうございます! – gordon613

3

2つのオブジェクトが等しいと比較すると、つまり、calcSmoothDaysが同じ値を返した場合、compare(object1、object2)== 1、compare(object2、object1)== 1という状況はありませんでしたか?

だから、値が等しい場合は物体1>オブジェクト2とオブジェクト2>オブジェクト1 ...

関連する問題