1. 简介
在 Kotlin 编程中,掌握如何初始化一个列表的列表(List of Lists)是非常常见的需求。这种结构也被称为二维数组或矩阵,本质上是一个列表,其每个元素本身又是一个列表。
在本文中,我们将介绍在 Kotlin 中初始化列表的列表的几种常见方式,并对比它们的适用场景和差异。
2. 什么是列表的列表?
在 Kotlin 中,列表的列表本质上就是一个二维结构,如下图所示:
如图所示,外层列表代表“行”,而内层列表代表“列”。这种结构非常适合表示表格、矩阵、二维网格等数据。
3. 使用 listOf()
方法
listOf()
是 Kotlin 标准库中用于创建不可变列表的常用方法。我们可以通过嵌套调用 listOf()
来创建一个不可变的列表的列表:
@Test
fun `Creates an immutable list of immutable lists using listOf()`() {
val listOfLists = listOf(listOf(1, 2), listOf(3, 4), listOf(5, 6))
assertEquals(3, listOfLists.size)
assertEquals(listOf(1, 2), listOfLists[0])
assertEquals(listOf(3, 4), listOfLists[1])
assertEquals(listOf(5, 6), listOfLists[2])
}
✅ 优点:
- 可以精确控制每个子列表的内容
- 结构清晰,适合静态数据初始化
❌ 缺点:
- 手动写每个子列表不够灵活,适用于数据量小的场景
4. 使用 List
构造函数
我们也可以使用 List
或 MutableList
的构造函数来创建列表的列表。这种方式适用于需要动态生成相同结构的子列表的情况:
@Test
fun `Creates an immutable list of mutable lists using List constructor`() {
val listOfLists = List(3) { MutableList<Int>(2) { 0 } }
assertEquals(3, listOfLists.size)
assertEquals(listOf(0, 0), listOfLists[0])
assertEquals(listOf(0, 0), listOfLists[1])
assertEquals(listOf(0, 0), listOfLists[2])
}
✅ 优点:
- 可以动态创建多个相同结构的子列表
- 适合初始化默认值(例如全零矩阵)
❌ 缺点:
- 所有子列表内容相同,不能自定义每个子列表的内容
5. 使用 map()
方法
map()
是 Kotlin 中处理集合转换的常用方法,也可以用来创建列表的列表。它和 List
构造函数类似,适合批量生成具有相同结构的子列表。
5.1 创建不可变列表的不可变列表
@Test
fun `Creates an immutable list of immutable lists using map method`() {
val listOfLists = (0..2).map { _ -> (0..1).map { 0 } }
assertEquals(3, listOfLists.size)
assertEquals(listOf(0, 0), listOfLists[0])
assertEquals(listOf(0, 0), listOfLists[1])
assertEquals(listOf(0, 0), listOfLists[2])
}
✅ 优点:
- 可读性强,适合熟悉函数式编程的开发者
- 可嵌套使用,灵活构建多维结构
❌ 缺点:
- 所有子列表内容相同,缺乏定制性
5.2 创建不可变列表的可变列表
我们也可以使用 map()
来创建外层不可变、内层可变的列表结构:
@Test
fun `Creates an immutable list of mutable lists using map method`() {
val listOfMutableLists = (0..2).map { mutableListOf<Int>() }
assertEquals(3, listOfMutableLists.size)
assertTrue(listOfMutableLists.all { it.isEmpty() })
}
✅ 适用场景:
- 外层结构固定,内层需要后续修改
- 适合构建动态数据结构的初始化模板
6. 总结
在 Kotlin 中,初始化一个列表的列表有以下几种方式,各有适用场景:
方法 | 是否可变 | 子列表是否可定制 | 适用场景 |
---|---|---|---|
listOf() |
不可变 | ✅ 可以 | 静态数据、手动初始化 |
List 构造函数 |
不可变(外层) | ❌ 否 | 批量生成相同结构的子列表 |
map() |
不可变(外层) | ❌ 否 | 函数式风格,结构统一 |
📌 踩坑提示:
- 如果你希望子列表内容不同,**请使用
listOf()
**,其它方法生成的子列表内容是重复的 - 如果你需要后续修改子列表内容,请使用
mutableListOf()
创建子列表
根据实际需求选择合适的方法,可以提升代码的可读性和性能。