【java】Collections.sort()方法报异常:" Comparison method violates its general contract"的解决过程

背景:项目的一个封装好工具类,在本地运行正常,但在客户的运行环境下报异常。

一、异常信息如下(原信息没保存下来,在网上搜了一段相同的异常信息):

java.lang.IllegalArgumentException: Comparison method violates its general contract!
    at java.util.ComparableTimSort.mergeHi(ComparableTimSort.java:866)
    at java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:483)
    at java.util.ComparableTimSort.mergeCollapse(ComparableTimSort.java:404)
    at java.util.ComparableTimSort.sort(ComparableTimSort.java:213)
    at java.util.Arrays.sort(Arrays.java:1312)
    at java.util.Arrays.sort(Arrays.java:1506)
    at java.util.ArrayList.sort(ArrayList.java:1454)
    at java.util.Collections.sort(Collections.java:141)

二、查看源代码如下:

/*
	 * f  字段
	 * x -1 升序     1降序
	 * 
	 */
public static void sortInteger(List<Map<String, Object>> list,String f,Integer x) {
		Collections.sort(list,new Comparator<Map<String,Object>>() {  
			@Override
			public int compare(Map<String, Object> o1,Map<String, Object> o2) {//o1,o2是list中的Map,可以在其内取得值,按其排序,此例为升序,s1和s2是排序字段值  
					String o11=o1.get(f)+"";
					String o22=o2.get(f)+"";
					Integer v1 = 0;
				    Integer v2 = 0;
					if(WebUtils.isNumeric(o11)){
						v1 = Integer.parseInt(o11);
					}
					if(WebUtils.isNumeric(o22)){
						v2 = Integer.parseInt(o22);
					}
					if (v1 > v2) {
						return -x;
					} else {
						return x;
					}
				}
			});
 	}

当运行不报异常时,如下图:
在这里插入图片描述
三、原因分析,根据网上的资料,可知这里是没有考虑v1==v2的情况,当出现数据相等时,会出现异常。
另粘一段网上的原理解释:
那么比较的约束是什么呢?说明链接,大体如下:
在这里插入图片描述

  • sgn(compare(x, y)) == -sgn(compare(y, x))
  • ((compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0
  • compare(x, y)==0 implies that sgn(compare(x, z))==sgn(compare(y, z))
    for all z

因为没有对v1==v2的判断,所以sgn(compare(x, y)) == -sgn(compare(y, x))不成立,报异常。

四、修改后的代码:

public static void sortInteger(List<Map<String, Object>> list,String f,Integer x) {
		Collections.sort(list,new Comparator<Map<String,Object>>() {  
			@Override
			public int compare(Map<String, Object> o1,Map<String, Object> o2) {//o1,o2是list中的Map,可以在其内取得值,按其排序,此例为升序,s1和s2是排序字段值  
					String o11=o1.get(f)+"";
					String o22=o2.get(f)+"";
					Integer v1 = 0;
				    Integer v2 = 0;
					if(WebUtils.isNumeric(o11)){
						v1 = Integer.parseInt(o11);
					}
					if(WebUtils.isNumeric(o22)){
						v2 = Integer.parseInt(o22);
					}
					if (v1 > v2) {
						return 1;
					}else if (v1 < v2) {
						return -1;
					}else {
						return 0;
					}
				}
			});
 	}

修改后运行如下图,同源代码效果一致:
在这里插入图片描述

参考文章:https://blog.csdn.net/ghsau/article/details/42012365

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值