1. 简介

在 Kotlin 编程中,掌握如何初始化一个列表的列表(List of Lists)是非常常见的需求。这种结构也被称为二维数组或矩阵,本质上是一个列表,其每个元素本身又是一个列表。

在本文中,我们将介绍在 Kotlin 中初始化列表的列表的几种常见方式,并对比它们的适用场景和差异。

2. 什么是列表的列表?

在 Kotlin 中,列表的列表本质上就是一个二维结构,如下图所示:

Graphical representation of a List of Lists in 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 构造函数

我们也可以使用 ListMutableList 的构造函数来创建列表的列表。这种方式适用于需要动态生成相同结构的子列表的情况:

@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() 创建子列表

根据实际需求选择合适的方法,可以提升代码的可读性和性能。


原始标题:How to Initialize a List of Lists in Kotlin