Collections.sort()有效,但Collections.reverseOrder()会中断

时间:2014-12-11 15:28:44

标签: java sorting collections comparator illegalargumentexception

所以我有一行代码如下:

Collections.sort(lists, new SpecificComparator());

工作正常。但是当我试图按降序排列时......

Collections.sort(lits, Collections.reverseOrder(new SpecificComparator()));

......它打破了以下例外:

java.lang.IllegalArgumentException: Comparison method violates its general contract!

当我搜索Exception消息时,我找到了this Q&A,声明这是因为这种关系不是传递性的。我想我对一个关系如何在一个方向而不是在另一个方向上传递感到有点困惑。我对传递性的理解是A == B && B == C -> A == C,所以......

这是我的比较器:

public class SuperComparator implements Comparator<Item> {

    @Override
    public int compare(Item first, Item second) {
        Result a = first.getResult();
        Result b = second.getResult();
        if(a == null && b == null) return 0;
        if(b == null || b == Result.DISQUALIFIED) return 1;
        if(a == null || a == Result.DISQUALIFIED) return -1;
        return b.getIntValue() - a.getIntValue();
    }

}

...

public class SpecificComparator extends SuperComparator {

    @Override
    public int compare(Item first, Item second) {

        int rank = super.compare(first, second);

        if(rank != 0) return rank;

        BigDecimal thisAmount = first.getAmount() != null ? first.getAmount() : BigDecimal.ZERO;
        BigDecimal otherAmount = second.getAmount() != null ? second.getAmount() : BigDecimal.ZERO;

        return thisAmount.compareTo(otherAmount);
    }

2 个答案:

答案 0 :(得分:4)

如果您的两个项目都被取消资格,您的比较器将始终返回1,这是错误的。

如果您的商品都被取消资格并且您的问题将得到解决,请添加检查案例

答案 1 :(得分:1)

你的比较器当然不具有传递性。

确保3个项目A,B和C,如果A&gt; B和B&gt; C,然后A> C ;那你就没事了