Kotlin中检查字符串包含多子串的更优雅实现方式?
优化方案:更优雅的Kotlin字符串多子串检查写法
你的代码逻辑没问题,但Kotlin的标准库和语法特性可以让这段代码更简洁、易读且易维护,以下是几个可行的优化方向:
1. 用标准库all函数替代自定义check函数
Kotlin集合的all函数可以直接判断所有元素是否满足条件,完全可以替代你手写的循环检查逻辑。这样不用额外定义check函数,代码更紧凑:
fun main() { val debug_fingerprint: String? = "Company/device/device:11/3526.4353/0064504902000:userdebug/com-d,dev-keys" val dev_fingerprint: String? = "Company/device/device:11/526.4353/0064504902000:user/com-d,dev-keys" val user_fingerprint: String? = "Company/device/device:11/526.4353/0064504902000:user/com-p,release-keys" val osVariant = user_fingerprint?.run { when { listOf("userdebug", "dev-keys").all { contains(it) } -> "Userdebug" listOf("user", "dev-keys").all { contains(it) } -> "Userdevsigned" listOf("user", "release-keys").all { contains(it) } -> "User" else -> "Unknown variant" } } ?: "Unknown variant null" print(osVariant) }
这里用run替代let,可以直接在lambda里调用contains(上下文就是当前的fingerprint字符串),比let更简洁。
2. 封装规则为数据类,提升扩展性
如果后续需要新增更多变体规则,硬写when表达式会越来越臃肿。可以把每个变体的检查规则和名称封装成数据类,通过遍历查找匹配项:
data class VariantRule(val requiredSubstrings: List<String>, val displayName: String) fun main() { val debug_fingerprint: String? = "Company/device/device:11/3526.4353/0064504902000:userdebug/com-d,dev-keys" val dev_fingerprint: String? = "Company/device/device:11/526.4353/0064504902000:user/com-d,dev-keys" val user_fingerprint: String? = "Company/device/device:11/526.4353/0064504902000:user/com-p,release-keys" // 定义所有变体规则,新增规则只需加在这里 val variantRules = listOf( VariantRule(listOf("userdebug", "dev-keys"), "Userdebug"), VariantRule(listOf("user", "dev-keys"), "Userdevsigned"), VariantRule(listOf("user", "release-keys"), "User") ) val osVariant = user_fingerprint?.let { fingerprint -> variantRules.firstOrNull { rule -> rule.requiredSubstrings.all { fingerprint.contains(it) } }?.displayName ?: "Unknown variant" } ?: "Unknown variant null" print(osVariant) }
这种写法的好处是规则和业务逻辑分离,后续维护只需要修改variantRules列表,不用动判断逻辑。
3. 自定义扩展函数增强可读性
如果经常需要检查字符串包含多个子串,可以给String写个扩展函数,让代码语义更清晰:
fun String.containsAll(substrings: List<String>): Boolean = substrings.all { contains(it) } fun main() { val debug_fingerprint: String? = "Company/device/device:11/3526.4353/0064504902000:userdebug/com-d,dev-keys" val dev_fingerprint: String? = "Company/device/device:11/526.4353/0064504902000:user/com-d,dev-keys" val user_fingerprint: String? = "Company/device/device:11/526.4353/0064504902000:user/com-p,release-keys" val osVariant = user_fingerprint?.run { when { containsAll(listOf("userdebug", "dev-keys")) -> "Userdebug" containsAll(listOf("user", "dev-keys")) -> "Userdevsigned" containsAll(listOf("user", "release-keys")) -> "User" else -> "Unknown variant" } } ?: "Unknown variant null" print(osVariant) }
containsAll的名字直接表达了“包含所有子串”的含义,比直接写all { contains(it) }更易懂。
内容的提问来源于stack exchange,提问作者CrazyCSGuy
相关产品推荐
相关产品推荐

