Kotlin中按条件去重列表:保留Artifact最高版本实例
保留最高版本依赖的Kotlin实现方案
要解决同一groupId+artifactId组合下保留最高版本Artifact的问题,你可以通过分组+版本比较筛选的方式实现,具体步骤如下:
1. 实现语义化版本比较器
版本字符串不能直接用普通字符串比较(例如"1.10.0"的字符串排序会小于"1.9.0"),需要一个能正确解析版本号的比较逻辑:
import java.util.Comparator // 版本字符串比较器,支持多段数字版本的语义化比较 val versionComparator = Comparator<String> { v1, v2 -> val v1Parts = v1.split(".").mapNotNull { it.toIntOrNull() } val v2Parts = v2.split(".").mapNotNull { it.toIntOrNull() } val maxSegmentCount = maxOf(v1Parts.size, v2Parts.size) for (i in 0 until maxSegmentCount) { val num1 = v1Parts.getOrElse(i) { 0 } val num2 = v2Parts.getOrElse(i) { 0 } if (num1 != num2) return@Comparator num1 - num2 } 0 // 两段版本完全一致 }
2. 分组筛选最高版本Artifact
通过groupBy将依赖按groupId和artifactId的唯一组合分组,再从每组中筛选出版本最高的实例:
// 示例输入列表 val artifacts = listOf( Artifact("com.squareup.okio", "okio-jvm", "3.2.0"), Artifact("org.jetbrains.kotlin", "kotlin-stdlib-jdk8", "1.6.20"), Artifact("org.jetbrains.kotlin", "kotlin-stdlib-common", "1.5.20"), Artifact("org.jetbrains.kotlin", "kotlin-stdlib-common", "1.6.21"), Artifact("org.jetbrains", "annotations", "13.0") ) // 筛选逻辑:分组后取每组最高版本 val filteredArtifacts = artifacts .groupBy { Pair(it.groupId, it.artifactId) } // 按groupId+artifactId分组 .values .map { group -> // 从分组中找出版本最高的Artifact group.maxWithOrNull(Comparator.comparing(Artifact::version, versionComparator))!! } // 打印结果 filteredArtifacts.forEach { println(it) }
执行后会输出你期望的结果:
Artifact(groupId=com.squareup.okio, artifactId=okio-jvm, version=3.2.0) Artifact(groupId=org.jetbrains.kotlin, artifactId=kotlin-stdlib-jdk8, version=1.6.20) Artifact(groupId=org.jetbrains.kotlin, artifactId=kotlin-stdlib-common, version=1.6.21) Artifact(groupId=org.jetbrains, artifactId=annotations, version=13.0)
额外说明
- 如果你的版本包含预发布标签(如
1.6.21-alpha),可以扩展版本比较器的逻辑,比如优先选择稳定版本,或按预发布标签的规则排序。 - 使用
maxWithOrNull比先排序再取第一个的效率更高,因为它不需要对整个分组排序,仅需遍历一次找到最大值。
内容的提问来源于stack exchange,提问作者Pranav Purwar
相关产品推荐
相关产品推荐

