CompareTo 是可传递的
CompareTo is transitive
我有一个看起来像这样的 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
错误。我做了 google 一点,我认为这是因为有些字段比较 null
。但是我不知道如何解决这个问题,或者如果我是对的,为什么会出现这个错误。
比较应该这样进行:第一次比较type
,然后比较bookingDate
,第三次比较journalId
,最后比较account
。所有比较都应该是升序的。
type
永远不会为空
bookingDate
可能为空
journalId
可能为空
account
永远不会为空
编辑:
遗憾的是我无法实现该方法,所以顺序是按需要的。然而,我解决了我遇到的问题,因为存储过程产生了 2 个结果集,其中第二个是根据需要排序的,所以我唯一要做的就是使用第二个结果集而不是第一个。
您忽略了 bookingDate
and/or journalId
一个为空而另一个为非空的情况。
您需要处理 一个 实例具有空值 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);
}
我有一个看起来像这样的 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
错误。我做了 google 一点,我认为这是因为有些字段比较 null
。但是我不知道如何解决这个问题,或者如果我是对的,为什么会出现这个错误。
比较应该这样进行:第一次比较type
,然后比较bookingDate
,第三次比较journalId
,最后比较account
。所有比较都应该是升序的。
type
永远不会为空bookingDate
可能为空journalId
可能为空account
永远不会为空
编辑:
遗憾的是我无法实现该方法,所以顺序是按需要的。然而,我解决了我遇到的问题,因为存储过程产生了 2 个结果集,其中第二个是根据需要排序的,所以我唯一要做的就是使用第二个结果集而不是第一个。
您忽略了 bookingDate
and/or journalId
一个为空而另一个为非空的情况。
您需要处理 一个 实例具有空值 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);
}