5

试图理解以下输出:

public class CommunicationComparator implements Comparator<Communication> {
    @Override
    public int compare(Communication comm1, Communication comm2) {
        long t1 = comm1.getDate().getTime();
        long t2 = comm2.getDate().getTime();
        return (int) (t2 - t1);
    }
}

getDate() 方法返回 java.sql.Timestamp。

这是排序前的输出:

for (Communication n : retVal) {
    System.out.println(n.getDate().toString());
}

2012-10-03 10:02:02.0
2012-10-07 03:02:01.0
2012-10-08 13:02:02.0
2012-10-09 03:02:00.0
2012-11-26 10:02:05.0
2012-11-28 11:28:11.0
2012-12-03 12:03:01.0
2012-12-06 15:03:01.0
2012-12-13 14:03:00.0
2012-12-28 11:03:00.0
2012-12-28 13:49:21.0

之后:

Collections.sort(retVal, new CommunicationsComparator());

2012-12-13 14:03:00.0
2012-12-06 15:03:01.0
2012-12-03 12:03:01.0
2012-11-28 11:28:11.0
2012-10-09 03:02:00.0
2012-10-08 13:02:02.0
2012-11-26 10:02:05.0
2012-10-07 03:02:01.0
2012-10-03 10:02:02.0
2012-12-28 13:49:21.0
2012-12-28 11:03:00.0

任何想法为什么底部的两个对象可能无法正确排序?我正在使用这个时间戳的 MySQL JDBC 实现。

4

5 回答 5

18

最后 2 个日期和更早日期之间的差异将溢出整数。

也许更好的解决方案是比较这些值,而不是减去它们。

    long t1 = comm1.getDate().getTime();
    long t2 = comm2.getDate().getTime();
    if(t2 > t1)
            return 1;
    else if(t1 > t2)
            return -1;
    else
            return 0;
于 2013-01-02T16:21:00.620 回答
6

如果差异大于约 25 天,则会发生溢出。(一个 int 不能以毫秒为单位表示比大约 25 天更大的时间差)。这将使比较不正确。

这可以通过将 return 语句更改为:

return Long.signum(t2 - t1);
于 2013-01-02T16:19:00.993 回答
6

您可以使用

return Long.compare(t2, t1);

但你最好比较日期。

return comm2.getDate().compareTo(comm1.getDate());
于 2013-01-02T16:35:52.760 回答
4

我的第一个想法是问题是溢出。 t1并且t2longs。不同的可能不适合 int。

我会检查的。

如果第二级比较对您来说足够好,您应该尝试:

return (int) ((t2 - t1)/1000);

这并不能保证不会出现溢出。我至少会添加一个测试。

我认为最好的答案不是我的。我最喜欢的是:

    if(t2 > t1)
        return 1;
    else if(t1 > t2)
        return -1;
    else
        return 0;
于 2013-01-02T16:15:51.500 回答
0

在 java 8 及更高版本中,我们可以通过以下方式以非常干净和简单的方式执行此操作:

list.stream().max(Comparator.comparing(YourCustomPojo::yourDateField))

这适用于任何具有支持的字段类型的 Pojo compareTo()java.sql.Timeastampjava.util.Date提供对这种方法的开箱即用支持。

在此处查看 java 文档

于 2021-06-16T11:45:35.130 回答