我正在研究Comparable界面,发现IllegalArgumentException当我放入size=50下面的程序时它正在抛出,并且当我放入时工作正常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;
}
}
Run Code Online (Sandbox Code Playgroud)
我不确定这个问题的根本原因,有人可以帮我解决这个问题.
下面给出了异常堆栈跟踪.
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)
Run Code Online (Sandbox Code Playgroud)
您违反了可比较合同.
实际上你不比较它们之间的两个对象,但是你只根据3的模数结果比较value当前TestObject对象的字段.你不使用TestObject在compareTo()方法中作为参数传递的对象.
假设您有List两个TestObject带有3as value字段的对象
这两个对象将返回-1:
if (value % 3 == 0) {
return -1;
}
Run Code Online (Sandbox Code Playgroud)
但根据规则:
实现者必须确保所有x和y的sgn(x.compareTo(y))== -sgn(y.compareTo(x)).(这意味着如果y.compareTo(x)抛出异常,x.compareTo(y)必须抛出异常.)
假设第一个对象是x,第二个对象是y.
如果y.compareTo(x)返回负数(例如-1),x.compareTo(y)则应返回正数(例如1).
我正在使用Comparable接口,发现当我在下面的程序中放置size = 50时它会抛出IllegalArgumentException并且当我把size = 5时工作正常
事实上,当你违反Comparable合同时,结果是不可预测的.它可能适用于某些特定值,不适用于其他特定值.
它可能在特定的JVM版本中工作,而在另一个版本中不起作用.
试图理解它失败的原因或者它对特定值的成功可能很有意思,但实际上没有用.
试图理解合同以尊重合同要好得多.因为今天它的工作正在进行中,但明天在未来的实施中,它可能会改变.只有API才是保证.
| 归档时间: |
|
| 查看次数: |
112 次 |
| 最近记录: |