You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kotlin中按指定优先级的多属性对Data对象列表排序?

问题描述

现有如下Data类定义:

class Data(region: String, language: String, version: String)

以及该类的实例:

var data1 = Data("Spain", "En, Pl", "")
var data2 = Data("Spain", "Ru, Es", "")
var data3 = Data("France", "Fr, En", "v1.0")
var data4 = Data("Germany", "", "v1.1")

(注:原代码存在重复定义data2的问题,已修正为data3和data4)

创建的列表为:

var list = mutableListOf(data1, data2, data3, data4)

需要按以下优先级从高到低对列表排序:

  • 排序因子1(最高优先级):region == "Spain"的元素排在最前;其次是region == "Europe";最后是region == "World";其他地区排在最后。
  • 排序因子2:包含"Es"的language属性优先于不包含的。
  • 排序因子3:版本号更高的元素排在前面(如v1.1优先于v1.0),版本号支持多位数字。

尝试了以下代码但结果错误:

list.sortedWith(compareBy({ it.region == "Spain"}, { it.language?.contains("Es") }, { it.version }))

请问如何正确实现这一排序逻辑?


正确实现方案

你的代码存在三个核心问题:

  1. 布尔值默认排序是false在前、true在后,与需求的优先级方向相反;
  2. 地区排序只判断了Spain,未覆盖Europe和World的优先级规则;
  3. 直接按字符串比较版本号会出现逻辑错误(比如v1.10会被判定为小于v1.2)。

以下是修正后的完整代码:

// 定义地区优先级映射,数值越小优先级越高
val regionPriority = mapOf(
    "Spain" to 0,
    "Europe" to 1,
    "World" to 2
)

// 自定义版本号比较器:解析为数字数组后逐位比较
val versionComparator = Comparator<Data> { a, b ->
    fun parseVersion(versionStr: String): List<Int> {
        return versionStr.removePrefix("v")
            .split(".")
            .filter { it.isNotEmpty() }
            .mapNotNull { it.toIntOrNull() }
    }
    val verA = parseVersion(a.version)
    val verB = parseVersion(b.version)
    // 逐位对比版本号,长度不足的补0
    for (i in 0 until maxOf(verA.size, verB.size)) {
        val numA = verA.getOrElse(i) { 0 }
        val numB = verB.getOrElse(i) { 0 }
        if (numA != numB) return@Comparator numB.compareTo(numA) // 降序排列,高版本在前
    }
    0
}

// 组合多优先级排序规则
val sortedList = list.sortedWith(
    compareBy<Data> {
        // 不在映射中的地区默认最低优先级(数值3)
        regionPriority.getOrDefault(it.region, 3)
    }.thenByDescending {
        // 包含"Es"的元素优先,用降序让true排在前面
        it.language.contains("Es")
    }.thenComparing(versionComparator)
)

关键逻辑说明:

  • 地区排序:通过映射表为目标地区分配优先级数值,确保Spain→Europe→World→其他地区的顺序,逻辑清晰且易于扩展。
  • 语言排序:使用thenByDescending反转布尔值排序方向,让包含"Es"的元素排在前面。
  • 版本号排序:将版本号解析为整数数组,逐位对比(长度不足补0),避免字符串比较的缺陷,同时实现高版本优先的降序排列。

内容的提问来源于stack exchange,提问作者NullPointerException

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 14:35:11