Kotlin复合条件排序

0 阅读1分钟

Kotlin排序背景

根据某字段或者某个index排序的场景,使用sortedBy+自定义comparator(comparator调用getter),即可满足简单排序需求。不过,在特定业务场景下,多种复杂条件的排序场景,通过上述办法无法解决,需要使用sortedWith方法处理。本文主要记述不同的sortedWith使用方式。

多字段、统一升降序

字段少、升降序一致时,直接传入多个gettercompareBy即可,实例代码如下:

val sorted = list.sortedWith(
    compareBy(User::age, User::score, User::name)
)

多字段、不同升降序

对于有判断优先级的多字段、多升降序的排序逻辑,可以组合使用compareBy+thenBy,示例代码如下:

data class User(  
    val name: String,  
    val age: Int,  
    val score: Int  
)

val list = listOf(  
    User("A", 20, 90),  
    User("B", 20, 85),  
    User("C", 18, 95)  
)

val sorted = list.sortedWith(  
    compareBy { it.age }  
        .thenByDescending { it.score }  
        .thenBy { it.name }  
)

复杂逻辑

当排序逻辑相当复杂时,需要自定义comparator,实例代码如下:

data class Person(
    val name: String,
    val age: Int,
    val isVip: Boolean,
    val score: Int
)

// list自行补充
val list = listOf<Person>()

val sorted = list.sortedWith { a, b ->
    when {
        a.isVip && !b.isVip -> -1
        !a.isVip && b.isVip -> 1
        a.age != b.age -> a.age - b.age
        else -> b.score - a.score
    }
}

上述写法中算数减法可能会溢出,但概率较小,等价的写法可能如下:

val sorted = list.sortedWith { a, b ->
    compareValuesBy(
        a, b,
        { !it.isVip },   // VIP 在前
        { it.age },
        { -it.score }
    )
}