我正在使用自定义比较器对二维数组进行排序,在某些情况下会出现以下错误:
java.lang.IllegalArgument异常:比较方法违反其一般契约!在行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
类实现时一切正常:
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;
}
}
}
}
我能知道第一次实现< code>SortComparator时抛出错误的原因吗?
问题是您的第一个 SortComparator
实现永远不会返回 0
。
因此<code>SortComparator。compare(a,a)永远不能返回0
,因为它是
实现的“通用合同”所要求的。
事实上,<code>SortComparator。compare(a,a)
将返回1
。
实际的合同在javadoc中。它说的是:
符号sgn(表达式)
指定1数学符号函数,根据表达式的值是负的、零的还是正的,它被定义为返回-1、0或1中的一个。
实现者必须确保所有 x
和 y 的 sgn(compare(x, y)) == -sgn(compare(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/0坐标的坐标系中是上、下、最左还是最右。这些点是double类型的。下面是错误消息:
从昨天开始,我的代码中出现了错误,我不知道为什么!我用谷歌搜索了很多,找到了这个堆栈帖子。 我使用这个功能按名称对用户进行排序并创建日期。这个功能已经工作了2年,现在我收到一个用户的错误,我不知道发生了什么变化。我试图检查我的数据是否有任何损坏,但找不到任何问题。 读完zhe Stack-Post后,我仍然没有完全理解问题出在哪里,或者我的项目发生了什么变化。
以下几行: 返回以下异常:比较方法违反了其一般约定! 我知道这个异常通常是在没有正确实现比较方法时产生的,但是在我的例子中,它的实现是相当明显的: 正如您所看到的,目标是按照值的hashValue属性对值进行排序。 任何关于我做错了什么的想法/提示将不胜感激! 谢谢托马斯
我已经检查了以前关于这个话题的帖子-这个和这个。尽管如此,我还是想不出在我下面给出的代码中违反合同的情况是如何发生的。 我使用它的方式如下: iterTypeScoreMap声明如下 映射(iterTypeScoreMap)在排序过程中可能会改变,这就是为什么我复制了一份列表,然后对它调用sort。 既然我使用的是Double的内置compareTo方法,那么这不应该考虑合同吗?另一件让调试变得困
是的,我知道有很多问题与相同的问题,但我似乎真的找不到我的比较器有什么问题。 所以,这里是: 代码非常简单:我需要根据它们如何改变我的主要结构对一些对象进行排序,并且我首先想要最高值。 由于计算或对象的影响可能需要一些时间,我只是缓存值以便重用它们,因此在排序之前,我检查是否有缓存值或是否需要计算它。 一旦我计算出将< code>m1或< code>m2应用于我的结构的结果,我就将更改恢复。 你可