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)));

问题是我经常得到 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()))