java.lang.IllegalArgumentException: Comparison method violates its general contract!

參考:

【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。拿來即用。再根據實際業務需求,做正序或倒序!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章