比较对象的两个日期属性时出现异常 'Comparison Method Violates Its General Contract!'
Exception 'Comparison Method Violates Its General Contract!' when comparing two date properties of an object
首先,我已经看过很多关于这个异常的问题和答案,但大多数只是关于比较简单的整数或相同的属性。
我拥有的是一个有两个日期的对象,当一个日期为空时,我将使用另一个日期进行比较,例如 class:
public class MyClass {
private LocalDate primaryDate;
private LocalDate secondaryDate;
private String Code;
}
比较方法为:
private List<MyClass> sortByDates(final List<MyClass> listOfClass) {
Comparator<MyClass> comparator = ((Comparator<MyClass>) (first, second) -> {
if (first.getPrimaryDate() == null || second.getPrimaryDate() == null) {
return first.getSecondaryDate().compareTo(second.getSecondaryDate());
}
return first.getPrimaryDate().compareTo(second.getPrimaryDate());
}).reversed().thenComparing(MyClass::getCodeAsLong);
return listOfClass.stream()
.sorted(comparator)
.collect(Collectors.toList());
}
Obs1:secondaryDate
永远不会为空,但我必须使用 primaryDate
作为第一个比较选项,并且 primaryDate
永远不会小于 secondaryDate
Obs2: Code
属性 保存为字符串但没有任何字母,所以可以转换为long
唯一的问题是您如何处理 primaryDate
.
的 null
检查以下示例:
MyClass
primaryDate
secondaryDate
A
null
1/1/2021
B
1/1/2023
1/1/2022
C
1/1/2024
1/1/2020
根据你的比较器,B > A 和 A > C 这意味着 B > C
但是,当您将 B 与 C 进行比较时。B < C,这违反了“一般合同”。
一般来说,比较nullable字段时,我们可以利用nullsFirst
or nullsLast
:
Comparator<MyClass> comparator = Comparator.nullsFirst(Comparator
.comparing(MyClass::getPrimaryDate))
.thenComparing(MyClass::getSecondaryDate)
.reversed()
.thenComparing(MyClass::getCodeAsLong);
首先,我已经看过很多关于这个异常的问题和答案,但大多数只是关于比较简单的整数或相同的属性。 我拥有的是一个有两个日期的对象,当一个日期为空时,我将使用另一个日期进行比较,例如 class:
public class MyClass {
private LocalDate primaryDate;
private LocalDate secondaryDate;
private String Code;
}
比较方法为:
private List<MyClass> sortByDates(final List<MyClass> listOfClass) {
Comparator<MyClass> comparator = ((Comparator<MyClass>) (first, second) -> {
if (first.getPrimaryDate() == null || second.getPrimaryDate() == null) {
return first.getSecondaryDate().compareTo(second.getSecondaryDate());
}
return first.getPrimaryDate().compareTo(second.getPrimaryDate());
}).reversed().thenComparing(MyClass::getCodeAsLong);
return listOfClass.stream()
.sorted(comparator)
.collect(Collectors.toList());
}
Obs1:secondaryDate
永远不会为空,但我必须使用 primaryDate
作为第一个比较选项,并且 primaryDate
永远不会小于 secondaryDate
Obs2: Code
属性 保存为字符串但没有任何字母,所以可以转换为long
唯一的问题是您如何处理 primaryDate
.
的 null
检查以下示例:
MyClass | primaryDate | secondaryDate |
---|---|---|
A | null | 1/1/2021 |
B | 1/1/2023 | 1/1/2022 |
C | 1/1/2024 | 1/1/2020 |
根据你的比较器,B > A 和 A > C 这意味着 B > C
但是,当您将 B 与 C 进行比较时。B < C,这违反了“一般合同”。
一般来说,比较nullable字段时,我们可以利用nullsFirst
or nullsLast
:
Comparator<MyClass> comparator = Comparator.nullsFirst(Comparator
.comparing(MyClass::getPrimaryDate))
.thenComparing(MyClass::getSecondaryDate)
.reversed()
.thenComparing(MyClass::getCodeAsLong);