You can combine Comparator.nullsLast()
with Comparator.thenComparing()
.
For example for
@Data
class MyObject {
private String field1;
private String field2;
private String field3;
}
you can create a Comparator
like this:
Comparator<MyObject> combined =
Comparator.comparing(MyObject::getField1, Comparator.nullsLast(Comparator.naturalOrder()))
.thenComparing(MyObject::getField2, Comparator.nullsLast(Comparator.naturalOrder()))
.thenComparing(MyObject::getField3, Comparator.nullsLast(Comparator.naturalOrder()));
This will result in a Comparator
that first sorts by field1
; if it contains null
for one of the compared objects contain null
, it will be sorted after the other (nullsLast
). If the field is null
for both objects, the next field will be evaluated (thenComparing()
), until field3
is reached.
You can of course create a helper method
private static Comparator<MyObject> compareField(Function<MyObject, String> fieldExtractor) {
return Comparator.comparing(fieldExtractor, Comparator.nullsLast(Comparator.naturalOrder()));
}
so your combination comparator definition is shorter:
Comparator<MyObject> combined =
compareField(MyObject::getField1)
.thenComparing(compareField(MyObject::getField2))
.thenComparing(compareField(MyObject::getField3));