[英]Java unexpected IllegalArgumentException in sorting with Math.abs(diff)
在對雙打列表進行排序時,我有一些我沒想到的行為。 我的目標是對雙打列表進行排序,但是當兩個雙打彼此靠近時,我不在乎它們的順序(實際上,我使用Entry <>並將Double作為值,當兩個Double值很接近,我在其他方面進行了排序。
這是一個將拋出IllegalArgumentException的示例:
public static void main(String[] args) {
final float probabilitySortMargin = 0.2f;
Comparator<Double> comp = new Comparator<Double>() {
@Override
public int compare(Double o1, Double o2) {
// sort on probability first
double diff = Math.abs(o1 - o2);
if(diff > probabilitySortMargin)
// difference is more than desired range, sort descending
return Double.compare(o2 , o1);
return 0;
}
};
ArrayList<Double> vals = new ArrayList<>();
Random r = new Random(0);
for(int i=0;i<1000;i++)
vals.add(r.nextDouble());
for(int i=0;i<vals.size();i++)
for(int j=0;j<vals.size();j++)
if(comp.compare(vals.get(i), vals.get(j)) != -1 * comp.compare(vals.get(j), vals.get(i)))
System.out.println("Comparison failed");
Collections.sort(vals, comp);
}
導致
Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeHi(TimSort.java:899)
at java.util.TimSort.mergeAt(TimSort.java:516)
at java.util.TimSort.mergeCollapse(TimSort.java:441)
at java.util.TimSort.sort(TimSort.java:245)
at java.util.Arrays.sort(Arrays.java:1512)
at java.util.ArrayList.sort(ArrayList.java:1462)
at java.util.Collections.sort(Collections.java:175)
at some.package.Sample.main(Sample.java:10)
為什么會這樣呢? 即使很奇怪,也不會打印錯誤消息“比較失敗”。
您的compare
方法確實違反了Comparator
接口的約定。
實現者必須確保compare(x,y)== 0意味着所有z的sgn(compare(x,z))== sgn(compare(y,z))。
compare(0.1,0.2) == 0, but sgn(compare(0.1,0.35)) != sgn(compare (0.2,0.35))
絕不會打印“比較失敗”,因為您的方法沒有違反sgn(compare(x, y)) ==-sgn(compare(y, x))
要求。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.