Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin sorting nulls last

Tags:

sorting

kotlin

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; } 
like image 783
Alex Avatar asked Nov 25 '16 09:11

Alex


2 Answers

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 nulls 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 nulls 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)] 
like image 65
hotkey Avatar answered Sep 18 '22 17:09

hotkey


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)] 
like image 27
miensol Avatar answered Sep 19 '22 17:09

miensol