我有一个带有几个“可选”(不是java.util.Optional
)字段的类。我正在编写一个Lambda比较器,通过比较它们的属性子集来测试是否相等
我写
private final static Comparator<MyEntity> COMPARATOR_491 =
comparing(MyEntity::getIsin)
.thenComparing(MyEntity::getTMarketType)
.thenComparing(nullsFirst(comparing(MyEntity::getIsoCode)))
.thenComparing(MyEntity::getTaxRate)
.thenComparing(nullsFirst(comparing(MyEntity::getEndDate)));
问题是我经常收到
NullPointerException
。这是(几乎不可读)堆栈跟踪java.lang.NullPointerException: null
at java.util.Comparator.lambda$comparing$77a9974f$1(Comparator.java:469) ~[?:1.8.0_51]
at java.util.Comparator$$Lambda$40/221702765.compare(Unknown Source) ~[?:?]
at java.util.Comparators$NullComparator.compare(Comparators.java:83) ~[?:1.8.0_51]
at java.util.Comparator.lambda$thenComparing$36697e65$1(Comparator.java:217) ~[?:1.8.0_51]
at java.util.Comparator$$Lambda$42/770739971.compare(Unknown Source) ~[?:?]
at java.util.Comparator.lambda$thenComparing$36697e65$1(Comparator.java:216) ~[?:1.8.0_51]
at java.util.Comparator$$Lambda$42/770739971.compare(Unknown Source) ~[?:?]
at java.util.Comparator.lambda$thenComparing$36697e65$1(Comparator.java:216) ~[?:1.8.0_51]
at java.util.Comparator$$Lambda$42/770739971.compare(Unknown Source) ~[?:?]
我发现两个示例实体在结束日期方面有所不同。第一个实体具有非null属性,第二个实体具有null
我认为当一个或两个参数为null时,
nullsFirst
比较器可以为null安全。我究竟做错了什么?
最佳答案
nullsFirst(…)
返回的比较器返回一个比较器,该比较器处理要比较的一个或两个对象都是null
的情况。
因此,当您说nullsFirst(comparing(MyEntity::getIsoCode))
时,如果两个MyEntity
实例都不是null
,则您将得到一个比较器来处理一个或两个getIsoCode
实例均为null
的情况,并根据其自然顺序比较MyEntity
属性(不处理null
值)。
您想要实现的是comparing(MyEntity::getIsoCode, nullsFirst(naturalOrder()))
,指定用于比较属性值的null
-safe比较器。 getEndDate
属性也是如此。
您可以将它与thenComparing
融合为previousComparator.thenComparing(MyEntity::getIsoCode, nullsFirst(naturalOrder()))