Java使用Comparable接口排序含正负值坐标时结果异常
问题成因
排序逻辑异常的核心原因是compareTo方法中直接返回两个int值的差值,触发了整型溢出。
Java中int类型的取值范围固定为[-2147483648, 2147483647],复现用例里两个点的y值分别为-2147483645和2147483647,执行this.y - c.y计算时,差值为-4294967292,远小于int类型的最小存储边界,溢出后会被解析为正整数,直接让比较方法返回了完全相反的结果,最终导致排序顺序颠倒。
这种用两数差值做比较返回值的写法本身就存在隐患,只要参与比较的两个整数值差值超过int类型的存储范围,无论正负都可能触发排序错误,和值是否一正一负没有必然联系,只是测试用例刚好踩中了int的取值边界。
修复方案
- 彻底摒弃整数比较时直接返回差值的写法,改用对应封装类提供的静态比较方法,从语法层面规避溢出问题。
- 补充空输入的边界判断,避免传入空数组时触发异常。
修复后的可运行代码如下:
class pair implements Comparable<pair>{ int x, y; pair(int x, int y){ this.x = x; this.y = y; } public int compareTo(pair c){ // 替换原有减法逻辑,使用Integer自带比较方法彻底避免溢出 return Integer.compare(this.y, c.y); } } class Solution { public int findMinArrowShots(int[][] points) { // 空输入边界处理 if(points == null || points.length == 0){ return 0; } ArrayList<pair> point = new ArrayList<>(); for(int i=0; i<points.length; i++){ point.add(new pair(points[i][0], points[i][1])); } Collections.sort(point); int minarr=1; int prev =0; for(int i=1; i<point.size(); i++){ if(point.get(i).x > point.get(prev).y){ minarr++; prev = i; } } return minarr; } }
修复后传入给出的复现用例,点会按照y值升序正确排列,区间判断逻辑也会返回正确结果,不会再出现顺序颠倒的问题。如果后续用lambda写Comparator实现排序,比如Collections.sort(list, (a,b) -> a.y - b.y)这种写法也要同步规避,必须替换为Integer.compare(a.y, b.y)的形式。
内容的提问来源于stack exchange,提问作者Anand Sharma
相关产品推荐
相关产品推荐

