最近在做产品需求的时候上线了一个新的产品需求,给用户多了一种新的排序排序规则,更加方便用户找到自己想要的东西。新版本发布后,QA 给我发了一个 线上崩溃 bug 链接,具体内容如下:

记录线上APP一个排序比较引发的崩溃  Comparison method violates its general contract!-LMLPHP

看到上面的链接,我有点懵逼了,就这排序还能给我搞出 bug 来?看到抛出的异常信息,也没有见过,于是直接百度搜索了。

一百度,发现很多人遇到这个问题,下面简单说下出现这个问题的原因:

  • 自反性:当 两个相同的元素相比时,compare必须返回0,也就是compare(o1, o1) = 0;

  • 反对称性:如果compare(o1,o2) = 1,则compare(o2, o1)必须返回符号相反的值也就是 -1;

  • 传递性:如果 a>b, b>c, 则 a必然大于c。也就是compare(a,b)>0, compare(b,c)>0, 则compare(a,c)>0

相信很多人看到这里还是会很懵逼的,感觉自己写的代码是不会出现这个问题的,这里理解的主要难点是怎么复现这个崩溃。

任何问题在我们一开始看到的时候,都会觉得很奇怪,觉得自己写的代码是不会出现这种问题的,可是一旦复现后,就会突然顿悟了,还是有自己遗漏没有想到的 case 。

例子

demo1

其实违反上述规则最简单的例子就是如下: 

new Comparator<Student>() {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.getId() > o2.getId() ? 1 : -1;
    }
}
11-15 08:24