Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java “;比较法违反其总合同”;_Java - Fatal编程技术网

Java “;比较法违反其总合同”;

Java “;比较法违反其总合同”;,java,Java,我在谷歌上搜索了一些相同的问题,我知道原因。但是这次坠机只发生过一次,所以我来这里问你什么可能导致坠机 Collections.sort(downloadTasks, new Comparator<DownloadTask>() { @Override public int compare(DownloadTask lhs, DownloadTask rhs) { if (lhs == null || rhs == nu

我在谷歌上搜索了一些相同的问题,我知道原因。但是这次坠机只发生过一次,所以我来这里问你什么可能导致坠机

    Collections.sort(downloadTasks, new Comparator<DownloadTask>() {
        @Override
        public int compare(DownloadTask lhs, DownloadTask rhs) {
            if (lhs == null || rhs == null) return 0;
            return (int) (lhs.mTaskInfo.time - rhs.mTaskInfo.time);
        }
    });

这两种情况都有问题

if(lhs==null | | rhs==null)返回0

如果您有
[123,null,234]
,那么您可以将
123
null
进行比较,
null
234
进行比较,通过传递性,您应该得到
123
等于
234
。但这不是比较器返回的结果

这里的解决方案是不允许
null
或将所有
null
排序到底部(或顶部),即仅返回
0
是两个都
null
,否则返回
1
-1
(取决于
null
是左还是右)

返回(int)(lhs.mTaskInfo.time-rhs.mTaskInfo.time)

考虑将
Integer.MAX_值+1
0
进行比较。两者之间的差异是
Integer.MAX_值+1
。将该值转换为
int
将换行为
Integer.MIN\u值
。然后,相反的比较应给出
-Integer.MIN_值
,但是

这里的解决方案是使用
Long。比较(a,b)

比较方法的javadoc中详细记录了比较方法的“总合同”:

实施者必须确保所有
x
y
sgn(比较(x,y))==-sgn(比较(y,x))
。(这意味着
compare(x,y)
必须在且仅当
compare(y,x)
引发异常时才会引发异常。)

实现者还必须确保关系是可传递的:
((比较(x,y)>0)和&(比较(y,z)>0))
意味着
比较(x,z)>0

最后,实现者必须确保
compare(x,y)==0
意味着所有z的
sgn(compare(x,z))==sgn(compare(y,z))

那么,你违反了这三条规则中的哪一条全部3个

违反第一条规则是因为
time
是一个
long
,所以
(int)(lhs.mTaskInfo.time-rhs.mTaskInfo.time)
可以等于
整数.MIN\u值。如果将这两个参数翻转到
compare()
,结果仍然是
Integer.MIN\u值
,因为
int
值不能存储取反的值

第二条规则被违反,因为
int
溢出。由于
time
long
,因此我假设它们包含标准的毫秒值,
int
最多只能存储24天的值。假设输入是1月1日、1月15日、1月30日<代码>比较(1月1日,1月15日)
是+14天,而
比较(1月15日,1月30日)
是+15天,但是
比较(1月1日,1月30日)
应该是+29天,但它溢出的返回时间大约是-19天。哎呀

由于错误的空检查,违反了第三条规则。假设输入为空,1月1日,1月2日
<代码>比较(空,1月1日)是0,
比较(空,1月2日)
也是0,但是
比较(1月1日,1月2日)
是+1天

解决方案

int
溢出和
MIN\u值
问题可以通过使用轻松解决

对于
null
问题,您需要决定null应该首先排序还是最后排序。以下内容将首先对空值进行排序:

public int compare(DownloadTask lhs, DownloadTask rhs) {
    if (lhs == null) {
        if (rhs == null)
            return 0;
        return -1;
    }
    if (rhs == null)
        return 1;
    return Long.compare(lhs.mTaskInfo.time, rhs.mTaskInfo.time);
}
或单语句版本:

public int compare(DownloadTask lhs, DownloadTask rhs) {
    return (lhs == null ? (rhs == null ? 0 : -1)
            : (rhs == null ? 1 : Long.compare(lhs.mTaskInfo.time, rhs.mTaskInfo.time)));
}

什么撞车?你会得到什么错误,什么时候,用什么代码,发生了什么,你期望发生什么?看一看,因为标题上说错误是
比较方法违反了它的一般约定public int compare(DownloadTask lhs, DownloadTask rhs) {
    return (lhs == null ? (rhs == null ? 0 : -1)
            : (rhs == null ? 1 : Long.compare(lhs.mTaskInfo.time, rhs.mTaskInfo.time)));
}