2014-11-06 65 views
1

什么可以此异常的原因:java.lang.IllegalArgumentException比较方法违反了它的一般合约!在数据库#排序

java.lang.IllegalArgumentException: Comparison method violates its general contract! 
     at java.util.TimSort.mergeLo(TimSort.java:747) 
     at java.util.TimSort.mergeAt(TimSort.java:483) 
     at java.util.TimSort.mergeForceCollapse(TimSort.java:426) 
     at java.util.TimSort.sort(TimSort.java:223) 
     at java.util.TimSort.sort(TimSort.java:173) 
     at java.util.Arrays.sort(Arrays.java:659) 
     at java.util.Collections.sort(Collections.java:217) 
     ... 

我用比较像这样:

private Comparator<SomeObject> comporator = new Comparator<SomeObject>() { 
    public int compare(SomeObject o1, SomeObject o2) { 
     return Double.compare(o2.getValue(), o1.getValue()); 
    } 
}; 

public double getValue() { 
    double value = 0; 
    for (Parameter parameter : parametrs()) { 
     value = value + (parameter.getWeight() * parameter.getSomeValue(this)); 
    } 
    return value;//20.0, 23.0 ... 
} 

其中parameter.getSomeValue:

public int getSomeValue(SomeObject process) { 
    return (int) ((System.currentTimeMillis() - process.getPutTime())/1000); 
} 

在:

public void sort() { 
    synchronized (list) { 
     Collections.sort(list, comporator); 
    } 
} 

其中:

List<SomeObject> list = new ArrayList<SomeObject>(); 

我不能再现此异常,但它有时会出现。 此外,你可以给代码示例100%的情况下出现此问题?

回答

2

比较方法根据getValue()返回的值比较两个对象。由于该值可能会在连续调用同一对象的该方法时发生变化,因此可能会导致不一致。看起来价值取决于时间,这是一个坏主意。

假设您比较object1和object2并找出那个compare(object1, object2) < 0。现在,您将object2与object1进行比较,并找出compare(object2, object1) < 0。这违反了比较方法的契约,因为一个对象不能比另一个对象更小和更大。由于对getValue的每个调用给出的结果都不相同,而这个结果似乎随时间而增加,所以如果确定getValue()的所有其他参数在两个对象中相等,则以后调用的对象可能会有更高的getValue()

相关问题