标准库实践¶
Kotlin 标准库提供集合、字符串、范围、序列、IO、比较、时间、结果处理等基础能力。很多 Java 开发者迁移到 Kotlin 后,代码是否“像 Kotlin”,很大程度取决于是否能用好标准库。
本章不逐项翻译 API,而是整理真实项目中最常用、最容易替代 Java 样板代码的标准库实践。
集合构造¶
val readOnly = listOf("A", "B")
val mutable = mutableListOf("A", "B")
val set = setOf(1, 2, 3)
val map = mapOf("one" to 1, "two" to 2)
优先通过类型表达意图:
- 返回
List<T>:调用方只读。 - 返回
MutableList<T>:调用方可以修改。
不要把内部可变集合直接暴露出去。
安全访问¶
Java 常见异常式访问:
list.get(0);
Kotlin 提供安全替代:
val first = list.firstOrNull()
val item = list.getOrNull(index)
val only = list.singleOrNull()
函数名里的 OrNull 是重要契约:调用方必须处理没有结果的情况。
转换与过滤¶
val activeNames = users
.filter { it.active }
.map { it.name }
.sorted()
可空过滤:
val names: List<String?> = listOf("Ada", null, "Grace")
val nonNullNames: List<String> = names.filterNotNull()
类型过滤:
val strings = values.filterIsInstance<String>()
分组与关联¶
val usersByRole = users.groupBy { it.role }
val userById = users.associateBy { it.id }
val nameById = users.associate { it.id to it.name }
这些 API 通常比手写 HashMap 填充循环更清晰。
作用域函数¶
作用域函数不是魔法,只是让对象上下文更短:
val request = Request().apply {
method = "GET"
path = "/users"
}
response.also {
logger.info("response={}", it)
}
nullableUser?.let {
sendWelcomeEmail(it)
}
过度嵌套会降低可读性。代码复杂时,局部变量和普通 if 更好。
require/check/error¶
参数校验:
fun setAge(age: Int) {
require(age >= 0) { "age must be non-negative" }
}
状态校验:
check(connection.isOpen) { "connection must be open" }
不应发生的分支:
else -> error("unknown state: $state")
这比手写 if (...) throw ... 更统一,也能帮助智能转换。
Result¶
Result<T> 可用于表达成功或失败:
fun parseInt(input: String): Result<Int> =
runCatching { input.toInt() }
val value = parseInt("42")
.getOrElse { 0 }
注意:不要把所有异常都机械包装成 Result。对于业务错误,sealed class 结果类型常常更清晰;对于违反契约的错误,异常仍然合理。
字符串工具¶
text.isBlank()
text.isNullOrBlank()
text.trim()
text.substringBefore("@")
text.substringAfter("@")
text.removePrefix("Bearer ")
字符串模板:
val message = "User ${user.id}: ${user.name}"
多行字符串:
val sql = """
SELECT id, name
FROM users
WHERE active = true
""".trimIndent()
范围与进度¶
for (i in 1..10) {}
for (i in 1 until 10) {}
for (i in 10 downTo 1 step 2) {}
if (age in 0..120) {
println("valid")
}
until 不包含右边界,适合索引:
for (i in 0 until list.size) {
println(list[i])
}
但需要索引和值时优先:
for ((index, value) in list.withIndex()) {
println("$index -> $value")
}
use 关闭资源¶
Java try-with-resources:
try (var reader = Files.newBufferedReader(path)) {
return reader.readLine();
}
Kotlin:
File("input.txt").bufferedReader().use { reader ->
println(reader.readLine())
}
use 会在代码块结束后关闭资源,即使发生异常。
TODO 与 NotImplementedError¶
fun calculate(): Int {
TODO("not implemented yet")
}
TODO() 返回 Nothing,可以放在任意返回类型的位置。它适合开发占位,但不能留在生产路径中。
Java 迁移建议¶
- 用
map/filter/groupBy/associateBy替代简单循环填充集合。 - 用
firstOrNull/getOrNull/toIntOrNull替代可预期失败的异常。 - 用字符串模板替代字符串拼接。
- 用
require/check替代零散参数和状态校验。 - 用
use替代 try-finally 资源关闭。 - 不要为了“函数式”牺牲可读性,复杂流程仍可用普通循环。
实践建议¶
- 标准库函数名通常带语义提示,例如
OrNull、NotNull、To、By,阅读时要关注这些后缀。 - 小集合普通链式调用即可,大数据多步处理再考虑
Sequence。 - 公共 API 的集合返回类型尽量只读。
- 对可预期缺失使用可空值,对违反契约使用异常。
- 先写清楚,再写短;Kotlin 的简洁来自表达力,不是压缩行数。
参考¶
- Kotlin 标准库 API:https://kotlinlang.org/api/core/