Comparator.nullsFirst 当两者都为 null 时的工作
Working of Comparator.nullsFirst when both are null
我有一个包含多个 "optional"(不是 java.util.Optional
)字段的 class。我正在编写一个 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)));
- ISIN 不为空
- 市场类型不为空
- 代码可以为空
- 税率不为空
- 结束日期可以为空
问题是我经常得到 NullPointerException
。这是(几乎不可读的)堆栈跟踪
java.lang.NullPointerException: null
at java.util.Comparator.lambda$comparinga9974f(Comparator.java:469) ~[?:1.8.0_51]
at java.util.Comparator$$Lambda/221702765.compare(Unknown Source) ~[?:?]
at java.util.Comparators$NullComparator.compare(Comparators.java:83) ~[?:1.8.0_51]
at java.util.Comparator.lambda$thenComparing697e65(Comparator.java:217) ~[?:1.8.0_51]
at java.util.Comparator$$Lambda/770739971.compare(Unknown Source) ~[?:?]
at java.util.Comparator.lambda$thenComparing697e65(Comparator.java:216) ~[?:1.8.0_51]
at java.util.Comparator$$Lambda/770739971.compare(Unknown Source) ~[?:?]
at java.util.Comparator.lambda$thenComparing697e65(Comparator.java:216) ~[?:1.8.0_51]
at java.util.Comparator$$Lambda/770739971.compare(Unknown Source) ~[?:?]
我发现两个示例实体的结束日期不同。第一个实体有非空 属性,第二个有空
我认为当一个或两个参数为空时,nullsFirst
比较器可能是空安全的。
我做错了什么?
由 nullsFirst(…)
返回的比较器 returns 一个比较器,用于处理要比较的一个或两个对象是 null
.
的情况
所以当你说 nullsFirst(comparing(MyEntity::getIsoCode))
时,你会得到一个比较器来处理 MyEntity
个实例中的一个或两个实例是 null
的情况,并比较 getIsoCode
属性 根据它们的自然顺序(不处理 null
值),如果两个 MyEntity
实例都不是 null
.
您想要实现的是 comparing(MyEntity::getIsoCode, nullsFirst(naturalOrder()))
,指定要用于比较 属性 值的 null
安全比较器。同样适用于 getEndDate
属性.
您可以将其与 thenComparing
融合为 previousComparator.thenComparing(MyEntity::getIsoCode, nullsFirst(naturalOrder()))
我有一个包含多个 "optional"(不是 java.util.Optional
)字段的 class。我正在编写一个 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)));
- ISIN 不为空
- 市场类型不为空
- 代码可以为空
- 税率不为空
- 结束日期可以为空
问题是我经常得到 NullPointerException
。这是(几乎不可读的)堆栈跟踪
java.lang.NullPointerException: null
at java.util.Comparator.lambda$comparinga9974f(Comparator.java:469) ~[?:1.8.0_51]
at java.util.Comparator$$Lambda/221702765.compare(Unknown Source) ~[?:?]
at java.util.Comparators$NullComparator.compare(Comparators.java:83) ~[?:1.8.0_51]
at java.util.Comparator.lambda$thenComparing697e65(Comparator.java:217) ~[?:1.8.0_51]
at java.util.Comparator$$Lambda/770739971.compare(Unknown Source) ~[?:?]
at java.util.Comparator.lambda$thenComparing697e65(Comparator.java:216) ~[?:1.8.0_51]
at java.util.Comparator$$Lambda/770739971.compare(Unknown Source) ~[?:?]
at java.util.Comparator.lambda$thenComparing697e65(Comparator.java:216) ~[?:1.8.0_51]
at java.util.Comparator$$Lambda/770739971.compare(Unknown Source) ~[?:?]
我发现两个示例实体的结束日期不同。第一个实体有非空 属性,第二个有空
我认为当一个或两个参数为空时,nullsFirst
比较器可能是空安全的。
我做错了什么?
由 nullsFirst(…)
返回的比较器 returns 一个比较器,用于处理要比较的一个或两个对象是 null
.
所以当你说 nullsFirst(comparing(MyEntity::getIsoCode))
时,你会得到一个比较器来处理 MyEntity
个实例中的一个或两个实例是 null
的情况,并比较 getIsoCode
属性 根据它们的自然顺序(不处理 null
值),如果两个 MyEntity
实例都不是 null
.
您想要实现的是 comparing(MyEntity::getIsoCode, nullsFirst(naturalOrder()))
,指定要用于比较 属性 值的 null
安全比较器。同样适用于 getEndDate
属性.
您可以将其与 thenComparing
融合为 previousComparator.thenComparing(MyEntity::getIsoCode, nullsFirst(naturalOrder()))