将java compareTo排序为compareTo方法违反了其一般约定
我试图对一个集合进行排序,并得到以下异常:
java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.ComparableTimSort.mergeHi(ComparableTimSort.java:835)
at java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:453)
at java.util.ComparableTimSort.mergeCollapse(ComparableTimSort.java:376)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:182)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:146)
at java.util.Arrays.sort(Arrays.java:472)
at java.util.Collections.sort(Collections.java:155)
我知道compareTo的三份合同:
- x、 比较(y)>;0&&;y、 比较(z)>;0)表示x.与(z)相比>;0
- sgn(x.compareTo(y))=-sgn(y.compareTo(x))
- x、 compareTo(y)==0意味着sgn(x.compareTo(z))==sgn(y.compareTo(z))
代码如下。我可以看出,长期发展是有潜力的。intValue()将被截断,但据我所知,这不应违反合同
public class Bar implements Comparable<Bar>{
private static final int LOWER = 1;
private static final int HIGHER = -1;
private boolean isNoPriority;
private int priority;
private String tradeId;
private long tradeVersion;
public Bar(boolean isNoPriority, int priority, String tradeId,long tradeVersion) {
super();
this.isNoPriority = isNoPriority;
this.priority = priority;
this.tradeId = tradeId;
this.tradeVersion = tradeVersion;
}
@Override
public int compareTo(Bar o) {
if (isNoPriority && !o.isNoPriority){
return LOWER;
}
if (!isNoPriority && o.isNoPriority){
return HIGHER;
}
if (priority == o.priority) {
if (tradeId.compareToIgnoreCase(o.tradeId) == 0){
return Long.valueOf(tradeVersion).intValue() - Long.valueOf(o.tradeVersion).intValue();
}
else {
return tradeId.compareToIgnoreCase(o.tradeId);
}
}
else if (priority < o.priority) {
return LOWER;
}
else if (priority > o.priority){
return HIGHER;
} else {
return 0;
}
}
}
我无法理解与实施相比,这种做法有什么不正确之处
# 1 楼答案
你已经回答了自己的问题。如果其中一个长值被“截断”,它可能会从非常大的正数变为负数。这可能会导致在应返回负值时返回正值。它还可能导致对不相等的两个值返回0
不要对int值进行减法运算,而是使用Long compareTo
http://docs.oracle.com/javase/7/docs/api/java/lang/Long.html#compare(long,%20long)