我在 Comparable
接口(interface)上工作,发现当我将 size=50
放入下面的程序中并且正在运行时,它会抛出 IllegalArgumentException
当我输入 size =5
时很好。
public class Test {
public static void main(String[] args) {
int size = 50;
Test compareTest = new Test();
compareTest.test(size);
}
public void test(int size) {
List<TestObject> requests = new ArrayList<TestObject>();
for (int index = 0; index < size; index++) {
TestObject request = new TestObject();
request.value = index;
requests.add(request);
}
Collections.sort(requests);
}
}
class TestObject implements Comparable<TestObject> {
public int value;
public int compareTo(TestObject req) {
if (value % 3 == 0) {
return -1;
} else if (value % 3 == 1) {
return 0;
}
return 1;
}
}
我不确定这个问题的根本原因,有人可以帮我解决这个问题吗。
异常堆栈跟踪如下。
Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.ComparableTimSort.mergeLo(ComparableTimSort.java:744)
at java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:481)
at java.util.ComparableTimSort.mergeCollapse(ComparableTimSort.java:406)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:213)
最佳答案
您违反了 Comparable 契约(Contract)。
实际上你不比较两个对象,你只是比较当前TestObject
对象的value
字段,根据对3取模的结果。你不在 compareTo()
方法中不要使用作为参数传递的 TestObject
对象。
假设您有一个包含两个 TestObject
对象的 List
,3
作为 value
字段
这两个对象将返回 -1
:
if (value % 3 == 0) {
return -1;
}
但是根据规则:
The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y. (This implies that x.compareTo(y) must throw an exception iff y.compareTo(x) throws an exception.)
假设第一个对象是x
,第二个对象是y
。
如果 y.compareTo(x)
返回一个负数(例如 -1),那么 x.compareTo(y)
应该返回一个正数(例如 1)。
I was working on Comparable interface and found that it is throwing IllegalArgumentException when i put size=50 in the program below and is working fine when i put size =5
事实上,当您违反Comparable
契约时,结果是不可预测的。它可能适用于某些特定值,不适用于其他特定值。
它可能在特定的 JVM 版本中工作,而在另一个版本中不工作。
试图理解为什么它失败或成功的特定值可能很有趣,但实际上没有帮助。
努力理解契约(Contract)以尊重它要好得多。
因为今天它正在运行,但明天在未来的实现中,它可能会改变。只有 API 是保证。
关于java - 可比接口(interface)取决于大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44321624/