Arrays.sort.Collections.sort 排序出现的java.lang.IllegalArgumentException的异常
2023-09-11 14:15:39 时间
1.问题分析(Java 7)
在Java 6中Arrays.sort()和Collections.sort()使用的是MergeSort,而在Java 7中,内部实现换成了TimSort(做了大量优化的归并排序),其对对象间比较的实现要求更加严格:
Comparator的实现必须保证以下几点:
原则1. sgn(compare(x, y)) == -sgn(compare(y, x))
原则2. (compare(x, y) > 0) && (compare(y, z) > 0) 意味着 compare(x, z) > 0
原则3. compare(x, y) == 0 意味着对于任意的z:sgn(compare(x, z)) == sgn(compare(y, z)) 均成立
而我们的比较器代码是:
public int compare(Integer a, Integer b) {
return a > b ? 1 : -1;
}
- 违背了原则1:假设x的value为1,x的value也为1;那么compare(X, Y) ≠ –compare(Y, X) ,故会抛出java.lang.IllegalArgumentException的异常
2.异常重现
代码:
List<Integer> ases = new ArrayList<>(Arrays.asList( -1, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0,
-1, 0, 1, 1, 1, 0, 0, 0, 0, -1, 1, 1, 1, 1, -1, -1, -1, -1,1));
Collections.sort(ases, new Comparator<Integer>() {
@Override
public int compare(Integer a, Integer b) {
return a > b ? 1 : -1;
}
});
- PS:数组的大小必须大于等于32.小于32时不会出现java.lang.IllegalArgumentException异常.
- 原因是:java中默认的MIN_MERGE为32.若待排序的数组小于MIN_MERGE时,会使用Binary Sort,而不会使用TimSort.
3.解决方法
将我们的比较器的compare修改成:
public int compare(Integer a, Integer b) {
return a == b ? 0 : (a > b ? 1 : -1);
}
原文链接:https://blog.csdn.net/hspingcc/article/details/51896705
相关文章
- Java描述设计模式(23):访问者模式
- 你所不知道的库存超限做法 服务器一般达到多少qps比较好[转] JAVA格物致知基础篇:你所不知道的返回码 深入了解EntityFramework Core 2.1延迟加载(Lazy Loading) EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public? 藏在正则表达式里的陷阱 两道面试题,带你解析Java类加载机制
- Java 异常模型综述
- Java 异常处理(标准抛异常、异常处理、多异常、Finally、多线程异常处理、获取异常的堆栈信息、链试异常、自定义异常)
- Java 获取命令行输入数据(命令行输入,Scanner类)
- Java自学指南六、查一手资料
- JAVA单元测试框架-12-java代码重复执行失败的测试用例
- Java - CentOS下JDK的安装教程(及JAVA_HOME配置、以jdk1.8为例)
- memcached java client
- 34 异常机制 异常体系结构 Java把异常当做对象来处理 并定义一个基类java.lang.Throwable作为所有异常的超类 Error Exception
- 【Java】java: 无法访问org.testng.annotations.Test
- Java面试集合(五)
- Java基础语法:1.第一个java程序
- 【FAQ】【JAVA UI】HarmonyOS如何添加创建快捷键
- Java异常的中断和恢复
- java线程异常处理方法
- java异常的分类
- Java Stream 流如何进行合并操作
- netty系列之:java中的base64编码器
- Java .class 反编译 Luyten,导出 .java文件,查看jar 包目录,超级简单,实用
- Java编程常用数据转换:String与int互转、Date与String互转、BigDecimal与int比较(报错operator > cannot be applied to java.math.BigDecimal,int)
- java 和 C# 响应输出的相似度
- Java异常的概念和分类
- 【JAVA】浅谈java枚举类
- Java中java.util.Arrays参考指南
- Java基础八股文(背诵版)