Comparator.nullsFirst working when both values are zero
I have a class with multiple "optional" fields java.util.Optional
. I wrote a Lambda comparator to check for equality by comparing a subset of my attributes
I wrote
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 is not null
- The market type is not null.
- The code can be null.
- The tax rate is not zero.
- End date can be zero
The problem is that I often get NullPointerException
. This is a (barely readable) stack trace
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) ~[?:?]
I found that the two instances of the sample differ in the end date. The first object has a non-null property, the second has null
I thought the nullsFirst
-server could be null if one or both of the arguments are null.
What am I doing wrong?
source to share
The comparator returned nullsFirst(…)
returns a comparator that handles the case where one or both of the objects to compare are null
.
So when you say nullsFirst(comparing(MyEntity::getIsoCode))
, you end up with a comparator that handles the case where one or both instances MyEntity
are, null
and compares the property getIsoCode
according to their natural ordering (not processing values null
) if there is no MyEntity
instance null
.
What you want to achieve is comparing(MyEntity::getIsoCode, nullsFirst(naturalOrder()))
specify a null
-local comparator to be used to compare property values. The same goes for the property getEndDate
.
You can drain it with thenComparing
,previousComparator.thenComparing(MyEntity::getIsoCode, nullsFirst(naturalOrder()))
source to share