我有一个包含多个“可选”(不是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
我认为当一个或两个参数为空时,nullsFirst
comparer可以为null安全。
我做错了什么?
答案 0 :(得分:10)
nullsFirst(…)
返回的比较器返回一个比较器,用于处理要比较的一个或两个对象为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()))
融合到let plus1 = d => d += 1;
let plus2 = d => d += 2;
let write = d => document.write(d);
let execute = function(n,...functions){
functions.forEach((d)=>d(n));
}
execute(4,plus1,plus2,write);