1. 概述
本文将系统介绍在 Kotlin 中初始化 List
的各种方法。Kotlin 标准库为 List
数据类型提供了原生支持,其核心实现和相关工具方法定义在 kotlin.collections
包下的 Collections.kt
文件中。
作为 Kotlin 开发中的高频操作,掌握不同场景下如何正确创建 List 至关重要。下面我们从不可变列表、可变列表、转换构建等多个维度展开说明,帮你避开日常开发中的常见“坑”。
2. 创建空的不可变 List
使用 emptyList()
方法可以快速创建一个空的、不可变的 List:
@Test
fun emptyList() {
val emptyList = emptyList<String>()
assertTrue(emptyList.isEmpty(), "List is empty")
}
✅ 适用场景:函数返回空集合时推荐使用,避免返回 null
引发 NPE。
⚠️ 注意:该 List 不支持添加元素,调用 add()
会抛出 UnsupportedOperationException
。
3. 创建不可变 List
3.1 使用 listOf
通过 listOf
构造器可创建包含指定元素的不可变 List:
val readOnlyList = listOf<String>("John", "Doe")
- 返回的是
List<T>
接口实例 ✅ - 创建后无法修改内容 ❌
- 支持泛型声明,类型安全
3.2 基于已有 List 创建
你可以利用 展开操作符(spread operator) 将现有 List 元素复制到新 List:
val readOnlyList = listOf<String>("John", "Doe")
val secondList = listOf<String>(*readOnlyList.toTypedArray())
⚠️ 踩坑提示:必须调用
toTypedArray()
转成数组才能使用*
展开,直接写*readOnlyList
是编译错误!
3.3 过滤 null 值 —— listOfNotNull
当你想排除 null
元素时,listOfNotNull
是更简洁的选择:
val filteredList = listOfNotNull("A", "B", null)
// 结果: ["A", "B"]
✅ 推荐用于初始化时自动剔除无效值,减少后续判空逻辑。
4. 创建可变 List
4.1 使用 mutableListOf
这是最常用的可变 List 构造方式,返回 MutableList<T>
实例,支持增删改操作:
@Test
fun readWriteList() {
var mutableList = mutableListOf<String>()
mutableList.add("Sydney")
mutableList.add("Tokyo")
assert(mutableList.get(0) == "Sydney")
mutableList = mutableListOf("Paris", "London")
assert(mutableList.get(0) == "Paris")
}
✅ 特点:
- 动态扩容
- 提供
add
,remove
,clear
等方法 - 默认底层实现是
ArrayList
4.2 使用 arrayListOf
arrayListOf
显式创建 ArrayList
实例,继承自 MutableList
并实现 RandomAccess
接口,适合频繁随机访问的场景:
@Test
fun readWriteList() {
var arrList = arrayListOf<Int>()
arrList.add(1)
arrList.remove(1)
assert(arrList.size == 0)
arrList = arrayListOf(1, 2, 3, 4)
assert(arrList.size == 4)
}
✅ 优势:
- 随机访问性能好(O(1))
- 内部基于数组实现
❌ 场景限制:插入/删除中间元素成本较高(O(n))
💡 建议:除非特别需要强调
ArrayList
类型,否则优先使用mutableListOf
,API 更通用。
5. 从其他类型转换为 List
Kotlin 提供了丰富的扩展函数来完成类型转换。例如,将 Map
转为 List<Pair<K, V>>
:
@Test
fun fromMaps() {
val userAddressMap = mapOf(
"A" to "India",
"B" to "Australia",
"C" to null
)
val newList: List<Pair<String, String?>> = userAddressMap.toList()
assert(newList.size == 3)
}
输出结果为:
[(A, India), (B, Australia), (C, null)]
✅ 类似地,你还可以对 Set
、Array
等调用 .toList()
完成转换。
📌 记住:转换后的 List 是不可变的。
6. 使用构造器函数动态生成 List
6.1 使用 List(size) { }
和 MutableList(size) { }
通过指定大小和初始化 lambda,可批量生成元素:
fun dynamicBuild(){
val myList = List(10){
it.toString()
}
println(myList)
val myMutableList = MutableList(10){
it.toString()
}
myMutableList.add("11")
println(myMutableList)
}
输出:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
🔍 参数
it
表示当前索引(从 0 开始),非常适合用于生成序列数据。
6.2 使用 buildList
构建复杂结构
buildList
提供了一种 DSL 风格的方式来构建 List,在 builder action 中可像操作 MutableList
一样自由添加元素,最终返回一个只读的 List
:
fun build(){
val students = listOf<String>("Hertz","Jane")
val myList = buildList<String>(students.size + 1) {
add("Jitendra")
addAll(students)
}
println(myList)
}
输出:
[Jitendra, Hertz, Jane]
✅ 优点:
- 写法清晰,适合构建逻辑较复杂的列表
- 避免暴露可变引用
- 性能优于多次
+
拼接
📌 自 Kotlin 1.4 起引入,建议替代旧式的
mutableListOf().apply { ... }
模式。
7. 总结
方法 | 是否可变 | 是否过滤 null | 适用场景 |
---|---|---|---|
emptyList() |
❌ | - | 返回空集合占位 |
listOf() |
❌ | ❌ | 固定元素初始化 |
listOfNotNull() |
❌ | ✅ | 自动剔除 null |
mutableListOf() |
✅ | ❌ | 需要动态增删 |
arrayListOf() |
✅ | ❌ | 强依赖 ArrayList 特性 |
toList() |
❌ | 取决原数据 | Map/Set 转换 |
List(size){} |
❌ | 自定义 | 批量生成 |
buildList{} |
(临时可变)→ 最终不可变 | ✅ | 复杂构建逻辑 |
📌 最佳实践建议:
- 优先使用不可变 List(
listOf
/emptyList
),提升代码安全性 - 需要修改时再用
mutableListOf
- 复杂构建优先考虑
buildList
- 转换操作善用标准库扩展函数
文中所有示例代码均可在 GitHub 获取:https://github.com/Baeldung/kotlin-tutorials/tree/master/core-kotlin-modules/core-kotlin-collections-3