本文主旨是记录问题解决过程
出错的日志
Shutting down VM
--------- beginning of crash
FATAL EXCEPTION: main
Process: com.gezbox.deliver, PID: 25572
java.lang.IllegalArgumentException: Comparison method violates its general contract!
AndroidRuntime: at java.util.TimSort.mergeLo(TimSort.java:773)
AndroidRuntime: at java.util.TimSort.mergeAt(TimSort.java:510)
AndroidRuntime: at java.util.TimSort.mergeForceCollapse(TimSort.java:453)
AndroidRuntime: at java.util.TimSort.sort(TimSort.java:250)
AndroidRuntime: at java.util.Arrays.sort(Arrays.java:1523)
AndroidRuntime: at java.util.Collections.sort(Collections.java:238)
AndroidRuntime: at com.zzz.XXXFragment.refreshDate(XXXFragment.java:203)
AndroidRuntime: at com.zzz.XXXFragment$2.onSuccess(XXXFragment.java:152)
AndroidRuntime: at com.zzz.XXXFragment$2.onSuccess(XXXFragment.java:147)
AndroidRuntime: at com.gezbox.net.Callback.onResponse(Callback.java:79)
AndroidRuntime: at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:70)
AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:754)
AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95)
AndroidRuntime: at android.os.Looper.loop(Looper.java:165)
AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6365)
AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:883)
AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
原因
- JDK7中的Collections.Sort方法实现中,你的返回值需要严谨全面;
- 如果两个值是相等的,那么compare方法需要返回0,否则 可能 会在排序时抛错,而JDK6是没有这个限制的。
- 在在 JDK7 版本以上,Comparator 要满足自反性,传递性,对称性
代码使用的范例
说明:
1) 自反性:x,y 的比较结果和 y,x 的比较结果相反。
2) 传递性:x>y,y>z,则 x>z。
3) 对称性:x=y,则 x,z 比较结果和 y,z 比较结果相同
对比代码一般是这样的结构,写一段放着看看
Collections.sort(dataList, new Comparator<PackageInfo>() {
@Override
public int compare(PackageInfo item1, PackageInfo item2) {
return xxxxx.compare(xxxxx);
}
});
有个简单的解决办法
- 找出所有的条件语句
- 针对所有条件,列出所有的可能情况。然后遍历一遍,覆盖所有的路径
上代码
范例
Collections.sort(dataList, new Comparator<ProcessingOrderResponse.PackageInfo>() {
@Override
public int compare(ProcessingOrderResponse.PackageInfo item1, ProcessingOrderResponse.PackageInfo item2) {
if (TextUtils.equals(mContext.getResources().getString(R.string.task_order_return), item1.packageNo)) {
return 1;
} else if (TextUtils.equals(mContext.getResources().getString(R.string.task_order_return), item2.packageNo)) {
return -1;
} else {
return item1.packageNo.compareTo(item2.packageNo);
}
}
});
修改后的
Collections.sort(dataList, new Comparator<ProcessingOrderResponse.PackageInfo>() {
@Override
public int compare(ProcessingOrderResponse.PackageInfo item1, ProcessingOrderResponse.PackageInfo item2) {
if (TextUtils.equals(mContext.getString(R.string.task_order_return), item1.packageNo)
&& TextUtils.equals(mContext.getString(R.string.task_order_return), item2.packageNo)) {
return 0;
} else if (!TextUtils.equals(mContext.getString(R.string.task_order_return), item1.packageNo)
&& TextUtils.equals(mContext.getString(R.string.task_order_return), item2.packageNo)) {
return 1;
} else if (TextUtils.equals(mContext.getString(R.string.task_order_return), item1.packageNo)
&& !TextUtils.equals(mContext.getString(R.string.task_order_return), item2.packageNo)) {
return -1;
} else {
if (item1.packageNo.compareTo(item2.packageNo) > 0) {
return 1;
} else if (item1.packageNo.compareTo(item2.packageNo) == 0) {
return 0;
} else {
return -1;
}
}
}
});
简单说明
这里有三个判断条件
两个TextUtil.equals 以及String.compareTo
解决思路是
想讲两个TextUtil.equals这的所有路径都遍历,得到4个状态,分别给出1,0,-1这几个返回值
剩下的String.compareTo也遍历一遍,给出1,0,-1三个返回值
网上找了一圈,本来想看看java的源码,结果。。。。没找到源码,有知道的朋友麻烦告诉我一下,在此先谢过
本文记录了在使用Collections.sort方法时遇到的'Comparison method violates its general contract!'错误,原因是Comparator接口实现不严谨,需满足自反性、传递性和对称性。解决方案包括检查并确保compare方法的所有路径返回值正确,特别是相等值的情况。
7642





