java.lang.IllegalArgumentException: Comparison method violates its general contract, only in particular test case

huangapple go评论76阅读模式
英文:

java.lang.IllegalArgumentException: Comparison method violates its general contract, only in particular test case

问题

这是我的比较函数:

Arrays.sort(intervals, (a, b) -> {
    return (a[0] > b[0]) ? 1 : ((a[0] < b[0]) ? -1 : ((a[1] > b[1]) ? 1 : -1)); 
});

我认为我已经明确地为每个条件指定了返回值,当ab是大小为2的数组时,但我不知道为什么在一个测试用例中出现错误,而其他测试用例则正常运行:

java.lang.IllegalArgumentException: Comparison method violates its general contract:
    at line 903, java.base/java.utili.TimSort.mergeHi
    at line 520, java.base/java.utili.TimSort.mergeAt
    at line 448, java.base/java.utili.TimSort.mergeCollapse
    at line 245, java.base/java.utili.TimSort.sort
    at line 1442, java.base/java.utili.Arrays.sort
    at line 3, Solution.merge
    at line 54, __DriverSolution__.__helper__
    at line 84, __Driver__.main
英文:

Here is my comparator function:

Arrays.sort(intervals, (a, b)-&gt;{
    return (a[0] &gt; b[0]) ? 1 : ((a[0] &lt; b[0]) ? -1 : ((a[1] &gt; b[1]) ? 1 : -1)); 
});

I think I've clearly specified return value for each condition in a case when a and b are arrays of size 2, but I don't know why I'm getting this error in a single test case while others run properly:

java.lang.IllegalArgumentException: Comparison method violates its general contract:
    at line 903, java.base/java.utili.TimSort.mergeHi
    at line 520, java.base/java.utili.TimSort.mergeAt
    at line 448, java.base/java.utili.TimSort.mergeCollapse
    at line 245, java.base/java.utili.TimSort.sort
    at line 1442, java.base/java.utili.Arrays.sort
    at line 3, Solution.merge
    at line 54, __DriverSolution__.__helper__
    at line 84, __Driver__.main

答案1

得分: 1

如果你未能涵盖一个情况,你的代码甚至无法编译。

就目前而言,你的代码可以编译,但它并不满足比较方法的要求。这是一个不同的问题。

以下是一般约定:

  1. 如果a < b且b < c,则a < c。
  2. 如果a == b,则compare(a, b) 必须返回0。
  3. 如果a < b,则b > a。
  4. 如果你愿意,可以抛出异常。

你已经违反了这个约定:如果我将相同的值传递给你的比较方法,最后一个情况会发生,并且返回-1,这意味着:“a在a下面”,这违反了规则。

将最后一个节点(-1)展开为:(a[1] < b[1]) ? -1 : 0

英文:

If you had failed to cover a case, your code wouldn't even compile.

As is, your code compiles, but it doesn't fulfill the requirements of a compare method. Different problem.

Here is the general contract:

  1. If a<b and b<c, then a<c.
  2. If a==b, then compare(a, b) must return 0.
  3. If a<b then b &gt; a.
  4. you may throw exceptions if you want.

You've broken the contract: If I pass the same value to your compare method, the final case occurs, and -1 is returned, which is saying: 'a is below a', and that breaks the rule.

Expand that last node (the -1) to: (a[1] &lt; b[1]) ? -1 : 0.

答案2

得分: 0

a[1] 和 b[1] 交换时没有对称性。以下内容可以解决这个问题。

return (a[0] > b[0]) ? 1
       : (a[0] < b[0]) ? -1
       : (a[1] > b[1]) ? 1
       : (a[1] < b[1]) ? -1
       : 0;

对于这种结构性比较,应使用 Comparator 类。类似这样:

Arrays.sort(intervals, Comparator.comparing(c -> c[0]).thenComparing(c -> c[1]));
英文:

There is no symmetry when a[1] and b[1] are switched. The following would solve that.

return a[0] &gt; b[0]) ? 1
       : a[0] &lt; b[0] ? -1
       : a[1] &gt; b[1] ? 1
       : a[1] &lt; b[1] ? -1
       : 0; 

The Comparator class should be used for such structural comparisons.
Something like:

Arrays.sort(intervals, Comparator.comparing(c -&gt; c[0]).thenComparing(c -&gt; c[1]));

huangapple
  • 本文由 发表于 2020年8月18日 11:18:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/63461380.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定