CompareTo是传递性的

时间:2017-09-12 13:36:06

标签: java compare comparator compareto

我的POJO看起来像这样:

public class Pojo implements Comparable<Pojo> {

    private String type;

    private String journalId;

    private Date bookingDate;

    private Long account;

    private String description;

    private BigDecimal debit;

    private BigDecimal credit;

    ....
}

我希望对这些POJO的列表进行排序。目前,我的compareTo方法如下所示:

@Override
public int compareTo(EfdisJournal other) {
    int i = this.type.compareTo(other.type);
    if (i != 0)
        return i;
    if (this.bookingDate != null && other.bookingDate != null)
        i = this.bookingDate.compareTo(other.bookingDate);
    if (i != 0)
        return i;
    if (this.journalId != null && other.journalId != null)
        i = this.journalId.compareTo(other.journalId);
    if (i != 0)
        return i;
    return this.account.compareTo(other.account);
}

如果我使用此compareTo方法运行排序,则会出现此java.lang.IllegalArgumentException: Comparison method violates its general contract错误。我做了一点谷歌,我认为这是因为一些字段是null比较。但我不知道如何解决这个问题,或者我是否正确,为什么会出现错误。

比较应该是这样的:按type进行第1次比较,然后按bookingDate进行比较,按journalId进行第3次比较,最后按account进行比较。所有比较都应该是提升的。

  • type永远不会为空
  • bookingDate可能为null
  • journalId可能为null
  • account永远不会为空

编辑:

可悲的是,我无法实现该方法,因此订单是必要的。然而,我解决了我遇到的问题,因为存储过程产生了2个结果集,其中第二个是按需排序的,所以我唯一需要做的就是使用第二个结果集而不是第一个结果集。

2 个答案:

答案 0 :(得分:1)

您忽略了bookingDate和/或journalId为空的情况,而其他情况为非空。

答案 1 :(得分:1)

您需要处理一个实例具有空bookingDate,另一个具有非空bookingDate的情况。 您应该决定是否应该在具有非null bookingDate的事物之前或之后对具有null bookingDate的事物进行排序,并适当地编写compareTo。 (然后journalId也是如此。)然后你就可以获得一致排序的订单。

例如:

@Override
public int compareTo(EfdisJournal other) {
    int i = this.type.compareTo(other.type);
    if (i != 0) {
        return i;
    }
    if ((this.bookingDate==null) ^ (other.bookingDate==null)) {
        return (this.bookingDate==null ? -1 : 1);
    }
    if (this.bookingDate != null && other.bookingDate != null) {
        i = this.bookingDate.compareTo(other.bookingDate);
    }
    if (i != 0) {
        return i;
    }
    if ((this.journalId==null) ^ (other.journalId==null)) {
        return (this.journalId==null ? -1 : 1);
    }
    if (this.journalId != null && other.journalId != null) {
        i = this.journalId.compareTo(other.journalId);
    }
    if (i != 0) {
        return i;
    }
    return this.account.compareTo(other.account);
}