Comparison method violates its general contract

今天在做List中Object排序时,报错:

Comparison method violates its general contract

 我的方法是 使pojo实现Comparable接口,重写compareTo方法.

最原始的写法为:

    @Override
    public int compareTo(Object o) {
        if(!(o instanceof TopicReportDto)){
            new RuntimeException("比较类型不匹配");
        }

        TopicReportDto other = (TopicReportDto) o;

        if(other.getViews() == null || this.getViews() == null){
            return -1;
        }
if(other.getViews() > this.getViews()){ return 1; }else if(other.getViews() < this.getViews()){ return -1; }else{ return 0; } }

这种写法在JDK1.6运行并没有什么问题,但是在JDK1.7+运行就存在问题.

参考这两篇文章:

  http://blog.csdn.net/ghsau/article/details/42012365

  http://iamyida.iteye.com/blog/2255804

解决方法有两种:

  1.JVM中添加参数 : -Djava.util.Arrays.useLegacyMergeSort=true

  2.修改代码 : 修改compareTo 方法

为了避免项目部署到没没有设置JVM参数的机器上再次报错的情况出现,我选择修改代码.

修改代码的过程中,我尝试了很多方法,但是都没有成功.

在iteye哥们中有一句话提醒了我:

因为他写的代码里没有考虑对象o1和对象o2为Null的情况,即当o1与o2都为null时两者大小如何判定呢,当o1为null但o2不为null时两者大小又如何判定了呢,
同理当o2为null但o1不为null时两者大小又如何判定呢又不得而知,或许你又会说,我这两个对象不可能为null,但那是你认为,
JVM不知道,它只要求你的逻辑必须严谨,严格考虑各种情况下两者大小的判定原则。

 仔细阅读后豁然开朗,原来是在compareTo方法中还需要考虑到 各种 传入值为空的返回情况

在我上面的代码中只考虑到,两者其中一个为空值的情况,还存在 两者 都为空值的情况.

看来在新的JDK中,以后在做compareTo方法时,要注意:

  1.各种为空值的情况

  2.大于

  3.小于

  4.等于


 修改后的代码:

  @Override
    public int compareTo(Object o) {
        if(!(o instanceof TopicReportDto)){
            new RuntimeException("比较类型不匹配");
        }

        TopicReportDto other = (TopicReportDto) o;

        //判断传入值为空值情况
        if(other.getViews() == null && this.getViews() == null){
            return 0;
        }

        if(other.getViews() == null){
            return -1;
        }

        if(this.getViews() == null){
            return 1;
        }

        //如果不为空值,比较传入的值
//      return other.getViews().compareTo(this.getViews());
        if(other.getViews() > this.getViews()){
            return 1;
        }else if(other.getViews() < this.getViews()){
            return -1;
        }else{
            return 0;
        }
    }
原文地址:https://www.cnblogs.com/0xcafedaddy/p/6812068.html