当我对java.lang.IllegalArgumentException: Comparison method violates its general contract!
列表执行Collections.sort()
时,会抛出ISimulationResultSet
。
我没有找到不遵守合同的原因。
如果有人对原因有所了解,那么最好进行解释。
这是我正在使用的比较器:
public int compare(ISimulationResultSet r1, ISimulationResultSet r2) {
final float r1Esperance = r1.getResults().getEsperanceGainOuPerte();
final float r2Esperance = r2.getResults().getEsperanceGainOuPerte();
final float r1PrctCibleAtteinte = r1.getResults().getPrctCibleAtteinte();
final float r2PrctCibleAtteinte = r2.getResults().getPrctCibleAtteinte();
if (r1Esperance / r2Esperance > 1.05F)
return -1;
else if (r1Esperance / r2Esperance < 0.95F) {
return 1;
}
else {
if (r1PrctCibleAtteinte == r2PrctCibleAtteinte) {
if (r1Esperance > r2Esperance)
return -1;
else if (r1Esperance < r2Esperance)
return 1;
return 0;
}
else if (r1PrctCibleAtteinte > r2PrctCibleAtteinte)
return -1;
else if (r1PrctCibleAtteinte < r2PrctCibleAtteinte)
return 1;
}
return 0;
}
最佳答案
比较器必须是对称的,即sgn(compare(x, y)) == -sgn(compare(y, x))
(sgn
是此处的信号函数)。您的比较器不是这种情况:
设a1
和a2
分别表示x.getResults().getEsperanceGainOuPerte()
和y.getResults().getEsperanceGainOuPerte()
的值,并使b1
和b2
分别表示x.getResults().getPrctCibleAtteinte()
和y.getResults().getPrctCibleAtteinte()
的值。
现在考虑以下几点:
1.05 < a1 < 1.052
a2 = 1
b2 > b1
因此
a2 / a1 > 0.95
compare(x, y) == -1;// first (r1Esperance / r2Esperance > 1.05F) is true
compare(y, x) == -1; // first 3 conditions false, (r1PrctCibleAtteinte > r2PrctCibleAtteinte) is true
那违反了合同。