我已检查发生此异常的原因。你能指导我吗?我在下面的代码块中做错了什么?
Collections.sort(discountGroupDetailList, new Comparator<DiscountGroupDetail>() {
long bdsIdOne;
long bdsIdTwo;
public int compare(DiscountGroupDetail discountGroupDetailOne, DiscountGroupDetail discountGroupDetailTwo) {
boolean discOne;
boolean discTwo;
SimpleDateFormat DATE_FORMATER = new SimpleDateFormat("yyyy/MM/dd");
int compVal = 0;
discOne = discountGroupDetailOne != null && discountGroupDetailOne.getServiceId() != null
&& discountGroupDetailOne.getServiceId().getCodeAndVersion() != null
&& discountGroupDetailOne.getServiceId().getCodeAndVersion().getCodeDetail() != null
&& discountGroupDetailOne.getServiceId().getCodeAndVersion().getCodeDetail().getCode() != null;
discTwo = discountGroupDetailTwo != null && discountGroupDetailTwo.getServiceId() != null
&& discountGroupDetailTwo.getServiceId().getCodeAndVersion() != null
&& discountGroupDetailTwo.getServiceId().getCodeAndVersion().getCodeDetail() != null
&& discountGroupDetailTwo.getServiceId().getCodeAndVersion().getCodeDetail().getCode() != null;
if (discOne == true && discTwo == true) {
bdsIdOne = MessageBuilderHelper.getBaseDiscountServiceById(discountGroupDetailOne.getServiceId())
.getBdsIdNbr();
bdsIdTwo = MessageBuilderHelper.getBaseDiscountServiceById(discountGroupDetailTwo.getServiceId())
.getBdsIdNbr();
compVal = (int) (bdsIdOne - bdsIdTwo);
}
DateRange dateRangeOne = discountGroupDetailOne != null ? discountGroupDetailOne.getDateSegment() : null;
DateRange dateRangeTwo = discountGroupDetailTwo != null ? discountGroupDetailTwo.getDateSegment() : null;
if (compVal == 0 && dateRangeOne != null && dateRangeTwo != null) {
Date date = new Date();
compVal = DATE_FORMATER.format(date.parse(dateRangeOne.getStartDate())).compareTo(
DATE_FORMATER.format(date.parse(dateRangeTwo.getStartDate())));
}
DiscountCode discountTypeOne = (discountGroupDetailOne != null && discountGroupDetailOne
.getVolumeDiscountGroupDetail() != null) ? DiscountCode.getDiscount(discountGroupDetailOne
.getVolumeDiscountGroupDetail().getType()) : null;
DiscountCode discountTypeTwo = (discountGroupDetailTwo != null && discountGroupDetailTwo
.getVolumeDiscountGroupDetail() != null) ? DiscountCode.getDiscount(discountGroupDetailTwo
.getVolumeDiscountGroupDetail().getType()) : null;
boolean isFXG = ("FXG".equals(discountGroupDetailOne.getServiceGeography()) || (discountGroupDetailOne
.getServiceId() != null && "FXG".equals(discountGroupDetailOne.getServiceId().getOperatingCompany())))
&& ("FXG".equals(discountGroupDetailTwo.getServiceGeography()) || (discountGroupDetailTwo
.getServiceId() != null && "FXG".equals(discountGroupDetailTwo.getServiceId()
.getOperatingCompany())));
if (compVal == 0 && discountTypeOne != null && discountTypeTwo != null && isFXG) {
compVal = ((int) (Integer.parseInt(discountTypeOne.getDiscountID()) - Integer.parseInt(discountTypeTwo
.getDiscountID())));
}
return compVal;
}
});
}
答案 0 :(得分:3)
@immibis在我可以之前发现了答案。概括原则:假设您正在编写一个比较多对键的比较器。你想比较第一对,然后如果那不能给你一个&lt;或者&gt;回答,比较第二对,如果你还没有&lt;或&gt;,比较第三对,依此类推。
此处的规则是,在比较第一对之后,除非第一对中的键相等,否则您可能不会继续使用第二对。在你的情况下,如果两者都有“代码”并且代码相等,或者如果它们都 null ,则它们是相等的。如果只有一个代码为空,那么你的错误就是继续下一对。在这种情况下,他们并不相同。我猜你的想法是,如果一个项目没有代码,你就无法比较代码。 但你必须。您需要判断没有代码的项目是否小于具有代码的项目(或大于;它取决于您希望如何在排序的数组中看到它们);并且你必须检查它,并且如果左项具有空代码则返回(例如)负数,如果右项具有空代码则返回正数。
然后你需要对日期范围做同样的事情;如果一个参数具有日期范围而另一个参数没有,则它们不相等,您必须返回一个负数或正数,而不是继续进行第三个键。
答案 1 :(得分:1)
这几乎总是由于您的比较器不是传递的或不是非对称的。对于传递性,给定三个DiscountGroupDetail
个对象a
,b
和c
,如果a
位于b
之前且b
位于c
之前{1}},然后一般合同要求a
在所有情况下都在c
之前。同样,如果a
等于b
而b
等于c
,则a
等于c
。对于不对称,交换不返回a
的两个对象b
和0
的比较顺序必须返回相反符号的数字。
鉴于你的复杂逻辑,我很难准确确定出错的地方,但以上是你需要检查的内容。