美文网首页
Android Collections.sort()填坑

Android Collections.sort()填坑

作者: Provider | 来源:发表于2020-12-28 10:20 被阅读0次
    复现

    错误代码如下

    Collections.sort(dataList, new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            return o1 > o2 ? 1 : -1;
        }
    });
    

    这里看着也没啥问题啊,相同的代码运行在不同手机上为啥有的报错有的不报错呢?根据错误提示Comparison method violates its general contract!去查看源码后找到抛出导致这个错误代码的具体位置

    if (len1 == 1) {
        assert len2 > 0;
        System.arraycopy(a, cursor2, a, dest, len2);
        a[dest + len2] = tmp[cursor1];
    } else if (len1 == 0) {
        throw new IllegalArgumentException("Comparison method violates its general contract!");
    } else {
        assert len2 == 0;
        assert len1 > 1;
        System.arraycopy(tmp, cursor1, a, dest, len1);
    }
    

    查阅相关资料后发现说这种写法在Java JDK6中没有问题。在Java JDK6以后,Comparator要满足自反性、传递性、对称性,不然Arrays.sort、Collections.sort会报IllegalArgumentException异常。说明:

    • 自反性:x,y 的比较结果和y,x的比较结果相反。
    • 传递性:x > y,y > z,则x > z。
    • 对称性:x = y,则x,z比较结果和y,z比较结果相同。

    然而错误写法:o1 > o2 ? 1 : -1,并没有处理相等的情况,所以在实际使用中可能会出现异常。

    斗罗小剧场
    小舞:哥,这里我有个疑问了,运行的环境都是Java JDK8的,为啥有的手机不会闪退有的手机会闪退呢?
    小三:额......这......
    小三:小舞,哥现在修为等级还不够,等我魂力到达90级或许可以帮你解决这个问题!!!

    总结

    根据上面的分析,在Java JDK6以后,Comparator要满足自反性、传递性、对称性。所以正确的写法应该是

    Collections.sort(list, new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
                //return o1 - o2或者return o1.compareTo(o2)
                return o1.compareTo(o2);
        }
    });
    

    相关文章

      网友评论

          本文标题:Android Collections.sort()填坑

          本文链接:https://www.haomeiwen.com/subject/ujnbnktx.html