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

排序时出现Comparison method violates its general contract!错误求助

搞定「Comparison method violates its general contract!」报错

兄弟,这个报错是因为你的比较器逻辑违反了Java Comparator必须遵守的通用规则(自反性、对称性、传递性),咱们来捋清楚问题出在哪,以及怎么修复:

为啥会报错?

你代码里用了Math.round(StudentName1 - StudentName2)来返回比较结果,这简直是踩了比较器的大坑!举个例子你就懂了:
假设三个酒店的评分分别是3.3、3.6、3.9:

  • 3.3和3.6的差是-0.3,round后是0 → 你代码会认为这俩评分相等
  • 3.6和3.9的差是-0.3,round后也是0 → 同样认为相等
  • 但3.3和3.9的差是-0.6,round后是-1 → 认为3.3小于3.9
    这就违反了传递性规则:如果a等于b,b等于c,那a必须等于c,但这里a却小于c,Java的排序算法直接就炸了,抛出那个报错。

另外吐槽下,你的变量名起得太离谱了——StudentName1居然存的是酒店评分,这以后维护代码的人得骂街😂,建议改成rating1这种一目了然的名字。

正确的修复方案

给你两个靠谱的解法,随便选一个都能解决问题:

方案1:用Double自带的compareTo(最推荐)

Double类本身就实现了正确的比较逻辑,直接用就行,完全符合规则:

public static Comparator<HotelResult> HotelLowRatingComparator = new Comparator<HotelResult>() {
    public int compare(HotelResult s1, HotelResult s2) {
        Double rating1 = Double.valueOf(s1.getStarRating());
        Double rating2 = Double.valueOf(s2.getStarRating());
        // 升序排序,直接返回比较结果
        return rating1.compareTo(rating2);
    }
};

方案2:手动判断差值(避免自动装箱的话用这个)

如果不想用Double的包装类,直接用基本类型手动判断也很稳妥:

public static Comparator<HotelResult> HotelLowRatingComparator = new Comparator<HotelResult>() {
    public int compare(HotelResult s1, HotelResult s2) {
        double rating1 = s1.getStarRating();
        double rating2 = s2.getStarRating();
        if (rating1 < rating2) {
            return -1;
        } else if (rating1 > rating2) {
            return 1;
        } else {
            return 0;
        }
    }
};

最后再提个醒

以后别再用(int)(a - b)或者Math.round(a - b)来做比较了!浮点数的精度问题加上round的特性,很容易破坏比较器的规则,就算Java老版本不报错,排序结果也会乱得一塌糊涂。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:18:53