You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java使用自定义Comparator按因数个数排序不生效问题

问题根因

排序失效是因为自定义的Comparator不符合Java接口的返回契约,Arrays.sort使用的比较器要求必须遵循以下返回规则:

  • 当第一个参数应该排在第二个参数前面时,返回负整数
  • 当两个参数优先级相等时,返回0
  • 当第一个参数应该排在第二个参数后面时,返回正整数

原代码的比较器存在两个致命问题:

  • 完全没有返回负整数的逻辑分支:当fact_a > fact_b、以及因数个数相等但A1 > B的场景下,代码直接返回0,排序算法会判定两个元素优先级完全相等,不需要交换位置
  • 逻辑分支覆盖不全:仅处理了因数更少、同因数下数值更小两种需要后置的场景,其余所有场景都被判定为元素相等,最终排序算法不会调整任何元素顺序,输出和原数组完全一致。
修复方案

补全比较器的所有判断分支,严格遵循返回值契约即可。如果要实现「按因数个数降序排序,因数个数相同时按数值降序排序」的逻辑(和原代码预期逻辑一致),修复后的完整代码如下:

public void solve(){
    Integer[] A = new Integer[]{3,9,4,6,12,10,7}; 

    System.out.println(Arrays.toString(A));
    Arrays.sort(A, (A1, B) -> {
        int fact_a = calcFactors(A1);
        int fact_b = calcFactors(B);
        // 优先按因数个数降序排列
        if (fact_a != fact_b) {
            return fact_b - fact_a;
        }
        // 因数个数相同时,按数值降序排列
        return B - A1;
    });
    System.out.println(Arrays.toString(A));
}

public int calcFactors(int A){
    int count = 0;
    int sqrt = (int)Math.sqrt(A);
    for(int i =1;i<=sqrt;i++){
        if(A%i == 0) count+=2;
    }
    if(sqrt*sqrt == A) count--;
    return count;
}

修复后运行代码,输出结果为[12, 10, 6, 9, 4, 7, 3],符合排序预期。

注:如果需要按因数个数升序、数值升序排列,只需要把比较器的返回值调整为fact_a - fact_b和A1 - B即可。

内容的提问来源于stack exchange,提问作者Ulhas Ch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 22:57:32