2014-11-06 63 views
1

什麼可以此異常的原因:java.lang.IllegalArgumentException比較方法違反了它的一般合約!在數據庫#排序

java.lang.IllegalArgumentException: Comparison method violates its general contract! 
     at java.util.TimSort.mergeLo(TimSort.java:747) 
     at java.util.TimSort.mergeAt(TimSort.java:483) 
     at java.util.TimSort.mergeForceCollapse(TimSort.java:426) 
     at java.util.TimSort.sort(TimSort.java:223) 
     at java.util.TimSort.sort(TimSort.java:173) 
     at java.util.Arrays.sort(Arrays.java:659) 
     at java.util.Collections.sort(Collections.java:217) 
     ... 

我用比較像這樣:

private Comparator<SomeObject> comporator = new Comparator<SomeObject>() { 
    public int compare(SomeObject o1, SomeObject o2) { 
     return Double.compare(o2.getValue(), o1.getValue()); 
    } 
}; 

public double getValue() { 
    double value = 0; 
    for (Parameter parameter : parametrs()) { 
     value = value + (parameter.getWeight() * parameter.getSomeValue(this)); 
    } 
    return value;//20.0, 23.0 ... 
} 

其中parameter.getSomeValue:

public int getSomeValue(SomeObject process) { 
    return (int) ((System.currentTimeMillis() - process.getPutTime())/1000); 
} 

在:

public void sort() { 
    synchronized (list) { 
     Collections.sort(list, comporator); 
    } 
} 

其中:

List<SomeObject> list = new ArrayList<SomeObject>(); 

我不能再現此異常,但它有時會出現。 此外,你可以給代碼示例100%的情況下出現此問題?

回答

2

比較方法根據getValue()返回的值比較兩個對象。由於該值可能會在連續調用同一對象的該方法時發生變化,因此可能會導致不一致。看起來價值取決於時間,這是一個壞主意。

假設您比較object1和object2並找出那個compare(object1, object2) < 0。現在,您將object2與object1進行比較,並找出compare(object2, object1) < 0。這違反了比較方法的契約,因爲一個對象不能比另一個對象更小和更大。由於對getValue的每個調用給出的結果都不相同,而這個結果似乎隨時間而增加,所以如果確定getValue()的所有其他參數在兩個對象中相等,則以後調用的對象可能會有更高的getValue()

相關問題