Collections.sort()中的异常

时间:2014-01-11 13:53:14

标签: java collections comparator

当我使用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;
}

1 个答案:

答案 0 :(得分:4)

比较器必须是对称的,即sgn(compare(x, y)) == -sgn(compare(y, x))sgn是这里的signum函数)。比较器的情况并非如此:

a1a2分别表示x.getResults().getEsperanceGainOuPerte()y.getResults().getEsperanceGainOuPerte()的值,让b1b2表示{{}的值分别为1}}和x.getResults().getPrctCibleAtteinte()

现在考虑以下事项:

y.getResults().getPrctCibleAtteinte()

因此1.05 < a1 < 1.052 a2 = 1 b2 > b1

a2 / a1 > 0.95

这违反了合同。