參考:
【1】https://yq.aliyun.com/articles/47048
【2】http://blog.csdn.net/ghsau/article/details/42012365
今天碰到一個未見過的異常。
java.lang.IllegalArgumentException: Comparison method violates its general contract!
斷點發現是排序的問題。排序的代碼如下:
@Override
public int compareTo(Domain that) {
//大數字排前
if(this.num.doubleValue() > that.num){
return -1;
}
//最近時間排前
if(this.date.after(that.date)){
return 1;
}
return 0;
}
表示一臉矇蔽。感覺邏輯絕對OK的呀。參考了【1】【2】兩前輩的文章。才明白,原來是邏輯不夠嚴謹。
num只判斷了this > that的情況。 this == that 和 this < that未做判斷,date也是一樣
所以我認爲 compare是單向判斷的。 指定了this > that,但如果this < that , 程序不知道怎麼判斷了。不會智能的兼容這種情況。
compare要全排列式的。把所有可能產生的情況,都要判斷一下。
修改後的代碼是:
@Override
public int compareTo(Domain that) {
int numCompare = this.num.compareTo(that.num);
//大數字排前-數字倒序,所以返回正序取反
if(numCompare != 0){
return -numCompare;
}
int dateCompare = this.date.compareTo(that.date);
//最近時間排前,時間正序。返回正序結果
if(dateCompare != 0){
return dateCompare;
}
return 0;
}
優化後就是:
@Override
public int compareTo(Domain that) {
int numCompare = this.num.compareTo(that.num);
//大數字排前-數字倒序,所以返回正序取反
//最近時間排前,時間正序。返回正序結果
return numCompare != 0 ? -numCompare : this.date.compareTo(that.date);
}
總結:
排序的最終判斷,都會落到幾個包裝類型上。String,Number,Date ...
- String : ASCII碼順序
- Number : 數值順序
- Date : 時間正序
.....
而包裝類型jdk都已經做好了Compare。拿來即用。再根據實際業務需求,做正序或倒序!