2017-11-18 4 views
0

ローンのステータスがアクティブ、拒否、保留中、承認済みであるローンのコレクションをソートしようとしています。アクティブローンが最も優先順位が高く、他のものはどんな順序でも使用できます。私はComparatorインターフェースのcompare()を実装しました。発生原因:java.lang.IllegalArgumentException:比較メソッドが一般契約に違反しています

ここのここでの比較()

@Override 
public int compare(Object o1, Object o2) { 
    LoanAccountData loanAccountData1 = (LoanAccountData) o1; 
    LoanAccountData loanAccountData2 = (LoanAccountData) o2; 

    if (loanAccountData1.getStatusStringValue().equals("Active")) { 
     return -1; 
    } else { 
     return 1; 
    } 
} 
+3

2つのオブジェクトを完全に無視して比較しています。だからそれは意味をなさない。たとえば、両方のオブジェクトがアクティブな場合、aとbを比較するとa である必要があります。 –

答えて

2

:(Yを比較(== -sgn((x、y)を比較する)ことSGNを確認する必要があります

実装:here

あなたのコードは、このルールに違反します、x))すべてのxとyについて。

xのステータスがアクティブである場合、(これはそれが比較のみなら(yは、x)が例外をスローする場合、例外をスローしなければならない(x、y)を比較することを意味する)とyの状態でもありますアクティブな場合、compare(x, y)xが小さいと言いますが、compare(y, x)yが小さいと言います。

ここでやりたいことは、すべてのアクティブなアカウントをリストの先頭に並べ替えることだと思います。これは、両方のアカウントがアクティブであるか、または両方が他のものである場合、それらが等しいことを意味します。 1つのアカウントがアクティブな場合、それはより小さく見なされます。

LoanAccountData loanAccountData1 = (LoanAccountData) o1; 
LoanAccountData loanAccountData2 = (LoanAccountData) o2; 
boolean o1Active = loanAccountData1.getStatusStringValue().equals("Active"); 
boolean o2Active = loanAccountData2.getStatusStringValue().equals("Active"); 
if (o1Active == o2Active) { 
    return 0; 
} else if (o1Active) { 
    return -1; 
} else { 
    return 1; 
} 
+1

私のものより少し短くなりました。 Fine :) +1 – davidxxx

+0

https://docs.oracle.com/javase/7/docs/api/java/lang/Boolean.html#compare(boolean,%20boolean) –

+0

@JBNizetでもっと短くできます。あなたが読みやすさを失うことを指摘しています... – Sweeper

2

の実装:

if (loanAccountData1.getStatusStringValue().equals("Active")) { 
    return -1; 

あなたは第二の目的と比較することはありません。
loanAccountData1.getStatusStringValue().equals("Active")loanAccountData2.getStatusStringValue().equals("Active")の両方が真である場合は、0を返す必要があるため、対称的な原則に違反します。

public class LoanAccountDataComparatorByStatusActive implements Comparator<LoanAccountData> { 

    @Override 
    public int compare(LoanAccountData o1, LoanAccountData o2) {  

     boolean isData1StatusActive = o1.getStatusStringValue().equals("Active"); 
     boolean isData2StatusActive = o2.getStatusStringValue().equals("Active"); 

     // if both status active, these have the same rank 
     if (isData1StatusActive && isData2StatusActive){ 
      return 0; 
     } 

     if (isData1StatusActive){ 
      return -1; 
     } 

     if (isData2StatusActive){ 
      return 1; 
     } 
     // if no status active, these have the same rank 
     return 0; 
    } 

} 

注意をそれはgetStatusStringValue()がnullを返すことはありませんことを前提としていること:あなたが書くことができ、汎用Comparator


それ以外の場合は、必要なチェックを追加してから参照してください。 compareの契約によると

関連する問題