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)]

✅ 类似地,你还可以对 SetArray 等调用 .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


原始标题:Initialize a List in Kotlin