What would be a Kotlin way of sorting list of objects by nullable field with nulls last?
Kotlin object to sort:
@JsonInclude(NON_NULL) data class SomeObject( val nullableField: String? )
Analogue to below Java code:
@Test public void name() { List<SomeObject> sorted = Stream.of(new SomeObject("bbb"), new SomeObject(null), new SomeObject("aaa")) .sorted(Comparator.comparing(SomeObject::getNullableField, Comparator.nullsLast(Comparator.naturalOrder()))) .collect(toList()); assertEquals("aaa", sorted.get(0).getNullableField()); assertNull(sorted.get(2).getNullableField()); } @Getter @AllArgsConstructor private static class SomeObject { private String nullableField; }
You can use these functions from the kotlin.comparisons
package:
fun <T: Comparable<T>> nullsLast(): Comparator<T?>
, which constructs a comparator of something comparable that just puts null
s after all not-null values;
fun <T, K> compareBy(comparator: Comparator<in K>, selector: (T) -> K): Comparator<T>
, which accepts a comparator and a function that provides values for the comparator, combining them into a new comparator;
This will let you make a comparator that compares SomeObject
by nullableField
putting null
s last. Then you can simply pass the comparator to fun <T> Iterable<T>.sortedWith(comparator: Comparator<in T>): List<T>
, which sorts an iterable into a list using a comparator:
val l = listOf(SomeObject(null), SomeObject("a")) l.sortedWith(compareBy(nullsLast<String>()) { it.nullableField })) // [SomeObject(nullableField=a), SomeObject(nullableField=null)]
You can use compareBy
and pass nullsLast
as comparator like so:
val elements = listOf(SomeObject("bbb"), SomeObject(null), SomeObject("aaa")) val sorted = elements.sortedWith(compareBy<SomeObject,String?>(nullsLast(), { it.name })) println(sorted) //-> [SomeObject(name=aaa), SomeObject(name=bbb), SomeObject(name=null)]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With