我正在开发一个旧的应用程序,它最初是用Java6编写的,几年前升级到了Java7。
在这个应用程序中,我使用Collection.Sort通过实现Comparator接口,使用自定义的compare方法对列表进行排序。列表中的对象类型是具有3个属性companyName、Schedule和expirationdate的CompanySchedule。
列表可以包含多个具有相同companyName但具有唯一过期日期的对象。下面的比较函数在相同的companyName列表中以companyName和with的升序和到期日期的降序对列表进行排序。下面是方法的实现。
public int compare(CompanySchedule c1, CompanySchedule c2) {
int returnVal = 0;
int value = c1.getCompany().getName().compareTo(c2.getCompany().getName());
if (value == 0){
if (c1.getUseExpirationDate() == null || c2.getUseExpirationDate() == null){
returnVal = -1;
}
else{
int chkdate = c1.getUseExpirationDate().compareTo(c2.getUseExpirationDate());
if (chkdate == 0){
returnVal = 0;
}
else if (chkdate > 0){
returnVal = -1;
}
else if (chkdate < 0){
returnVal = 1;
}
}
}
else if (value < 0){
returnVal = -1;
}
else if (value > 0){
returnVal = 1;
}
return returnVal;
}我知道,当在上面的compare方法实现中不满足可传递属性时,将抛出错误java.lang.IllegalArgumentException: Comparison method violates its general contract。
是否有人可以帮助确定此方法将在何处违反传递性。谢谢你的帮助。
发布于 2020-02-10 21:36:26
我认为这里有一个问题:
if (c1.getUseExpirationDate() == null || c2.getUseExpirationDate() == null){
returnVal = -1;
}如果a.getUseExpirationDate() == null和b.getUseExpirationDate() == null,您将得到a
这破坏了一致性。这个方法可能有更多的问题,但我还没有全部检查过。
祝好运。
编辑
这段代码怎么样?
public int compare(CompanySchedule c1, CompanySchedule c2) {
int returnVal = 0;
int value = c1.getCompany().getName().compareTo(c2.getCompany().getName());
if (value == 0) {
if (c1.getUseExpirationDate() == null && c2.getUseExpirationDate() != null) {
returnVal = -1;
} else if (c1.getUseExpirationDate() != null && c2.getUseExpirationDate() == null) {
returnVal = 1;
} else if (c1.getUseExpirationDate() == null && c2.getUseExpirationDate() == null) {
returnVal = 0;
} else {
int chkdate = c1.getUseExpirationDate().compareTo(c2.getUseExpirationDate());
if (chkdate == 0) {
returnVal = 0;
} else if (chkdate > 0) {
returnVal = -1;
} else if (chkdate < 0) {
returnVal = 1;
}
}
} else if (value < 0) {
returnVal = -1;
} else if (value > 0) {
returnVal = 1;
}
return returnVal;
}
为了可比性,我尽量不对其进行太多更改,但应该对其进行重构。基本上,它确定空值比其他值小。
发布于 2021-12-01 12:03:31
我知道我来晚了,一旦我找到了解决方案,我基本上忘记了我问过这个问题。因此,正如我所提到的,该应用程序是用Java6编写的,然后根据我对集合的内部实现的理解,升级到了Java 7。
Sort方法将使用的算法从Merge sort更改为Tim Sort,Merge sort忽略compare方法实现的传递性属性,但是,Tim Sort要求compare方法实现是可传递的,否则将引发上述异常,因为我们有一个遗留应用程序,我们不想更改代码中的任何内容,因此我们在Sort实现中内部使用了jvm参数java.util.Arrays.useLegacyMergeSort=true Merge sort
https://stackoverflow.com/questions/60151470
复制相似问题