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。拿来即用。再根据实际业务需求,做正序或倒序!

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