Java &引用;“比较法违反总合同”;在对多维数组进行排序时

Java &引用;“比较法违反总合同”;在对多维数组进行排序时,java,arrays,sorting,comparator,Java,Arrays,Sorting,Comparator,我使用自定义比较器对二维数组进行排序,在某些情况下会出现以下错误: java.lang.IllegalArgumentException:比较方法违反了它的一般约定! 在第781行,java.base/java.util.TimSort.mergeLo 在第518行,java.base/java.util.TimSort.mergeAt 在第448行,java.base/java.util.TimSort.mergeCollapse 在第245行,java.base/java.util.TimS

我使用自定义比较器对二维数组进行排序,在某些情况下会出现以下错误:

java.lang.IllegalArgumentException:比较方法违反了它的一般约定! 在第781行,java.base/java.util.TimSort.mergeLo 在第518行,java.base/java.util.TimSort.mergeAt 在第448行,java.base/java.util.TimSort.mergeCollapse 在第245行,java.base/java.util.TimSort.sort 在第1442行,java.base/java.util.Arrays.sort

下面是引发此错误的代码:

class Solution {
    public int[][] merge(int[][] intervals) {
        Arrays.sort(intervals, new SortComparator());
    }
}

class SortComparator implements Comparator<int[]> {
    public int compare(int []a, int []b) {
        if(a[0] < b[0]) {
            return -1;
        } else if(a[0] > b[0]) {
            return 1;
        } else {
            if(a[1] < b[1]) {
                return -1;
            } else {
                return 1;
            }
        }
    }
}

我可以知道是什么原因导致
SortComparator
的第一个实现抛出错误吗?

问题是您的第一个
SortComparator
实现永远无法返回
0

因此,
SortComparator.compare(a,a)
永远不能返回
0
,这是
Comparator
实现的“总合同”所要求的

实际上,
SortComparator.compare(a,a)
将返回
1


实际合同在合同中。它说的是:

符号
sgn(表达式)
指定1数学符号函数,该函数定义为根据表达式的值是负、零还是正返回-1、0或1中的一个

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

[……]

x
y
是同一对象时,
sgn(compare(x,y))===-sgn(compare(y,x))
的唯一方法是如果
-sgn(compare(x,x))
对于所有
x
为零



1-吹毛求疵:我认为他们应该在这里使用“表示”而不是“指定”。

好的。所以你的意思是,如果两个值相同,总是有必要返回0。如果我在同样的情况下也返回1,这不好吗?在同样的情况下返回1是不好的。@StephenC最后一行有点棘手,谢谢你的解释,我认为还需要添加文档(IMHO)。请随时提交错误报告。(但更好的建议是建议他们在Java教程中用外行的术语解释comparator契约。)
class SortComparator implements Comparator<int[]> {
    public int compare(int []a, int []b) {
        if(a[0] < b[0]) {
            return -1;
        } else if(a[0] > b[0]) {
            return 1;
        } else {
            if(a[1] < b[1]) {
                return -1;
            } else if(a[1]> b[1]) {
                return 1;
            } else {
                return 0;
            }
        }
    }
}