java - 比较方法(compareTo)在不同的JVM中返回不同的结果

标签 java sorting comparator comparable compareto

我很困惑:我写了一个比较日期的比较器。但是,当我运行 junit 测试时,它会返回不同的结果,具体取决于我是在 IDE 还是在 Maven 中运行?!在我的 IDE 中它可以工作,但在 Maven 中它失败。在两个环境中使用相同的 1.8 jvm,但在 1.6 兼容模式的 Maven 中。 (请注意,这是一个遗留项目,使用 java.util.date 是不好的......(但这不是现在的重点)

这是 IDE 的输出(正确): 生日 [id=4,时间=Thu Sep 23 20:54:24 CEST 2010] 生日 [id=6,时间=Wed Feb 01 01:01:01 CET 2012] 生日 [id=5,时间=Wed Feb 01 01:01:02 CET 2012] 生日 [id=三,时间=Tue Jan 08 17:30:43 CET 2019] 生日 [id=one, ] 生日 [id=two, ]

这里是 Maven 的输出(不正确): 生日 [id=4,时间=Thu Sep 23 20:54:24 CEST 2010] 生日 [id=三,时间=Tue Jan 08 17:26:25 CET 2019] 生日 [id=5,时间=Wed Feb 01 01:01:02 CET 2012] 生日 [id=6,时间=Wed Feb 01 01:01:01 CET 2012] 生日 [id=one, ] 生日 [id=two, ]

代码如下(在 1.8 中运行成功,在 1.6 中运行失败):

import java.util.Date;

public class Birthday implements Comparable<Birthday>{

    private String id;
    private Date time;

    public String getId() {
        return this.id;
    }
    public Birthday(String id, Date time) {
        this.id=id;
        this.time=time;
    }
    public Date getTime() {
        return this.time;
    }
    public void setTime(Date time) {
        this.time = time;
    }
    @Override
    public int compareTo(Birthday o) {   
        //if both are null return 0 for equals
        if(this.time==null && o.getTime()==null) {
            return 0;
        }

        //null birthdays should always be last
        if(this.time==null) {
            return 1;
        }
        if(o.getTime() == null) {
            return -1;            
        }
        return this.time.before(o.getTime()) ? 0 : 1;
    }

    @Override
    public String toString() {
        return this.id+" "+this.time;
    }
}

@Test
public void testTime() {
    Birthday info1 = new Birthday("one",null);
    Birthday info2 = new Birthday("two", null);
    Birthday info3 = new Birthday("three",new Date());
    Birthday info4 = new Birthday("four",new Date(110,8,23,20,54,24));
    Birthday info5 = new Birthday("five",new Date(112,1,1,1,1,2));
    Birthday info6 = new Birthday("six",new Date(112,1,1,1,1,1));

    ArrayList<Birthday> dates = new ArrayList<Birthday>();
    dates.add(info1);
    dates.add(info2);
    dates.add(info4);
    dates.add(info3);
    dates.add(info5);
    dates.add(info6);

    Collections.sort(dates);

    for(Birthday bs: dates) {
        System.out.println(bs);
    }

    Assert.assertEquals(info4, dates.get(0));
    Assert.assertEquals(info6, dates.get(1));
    Assert.assertEquals(info7, dates.get(2));
    Assert.assertEquals(info5, dates.get(3));
    Assert.assertEquals(info3, dates.get(4));
    Assert.assertEquals(info1, dates.get(5));
    Assert.assertEquals(info2, dates.get(6));
}

这是怎么回事?

最佳答案

问题出在这一行:

return this.time.before(o.getTime()) ? 0 : 1;

如果该项目的时间早于其他项目的时间,则它们相等。这不是自反的,因此您违反了compareTo 的要求。

不同的 JVM 实现可以使用不同的排序算法,其中一个会出现此错误,而另一个则不会

关于java - 比较方法(compareTo)在不同的JVM中返回不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54096454/

相关文章:

c++ - 自定义链表排序方法

linux - 在结构列表上调用 std::sort 时将 const 作为 'this' 参数错误传递

Java-Selection 按 int 键对对象数组进行排序并显示在表中

java - 将对象类型和字段传递给比较器

Java:用Gson解析Json未知字段

java - 使用 Maven 测量集成测试覆盖率

java - 获取 JLabel 中具有特定坐标的像素的颜色

java - 具有内部比较器类的 PriorityQueue

algorithm - 将关系运算符列表优化为最小集

java - 有没有办法在javafx WebView中播放flash?