1. 概述
在 Kotlin 中,数组(Array)和列表(List)是两种常见但又略有差异的数据结构。虽然在实际使用中它们在性能和内存占用上可能略有不同,但在大多数场景下,我们使用的 List 实际上是 ArrayList,因此差异并不明显。
Kotlin 鼓励不可变性(immutability),即在数据更新时倾向于创建新的结构而不是修改原结构,这也让数组和列表之间的区别进一步缩小。
尽管如此,Kotlin 的一些标准库函数只接受 Collection 或其子类作为参数,因此了解如何将数组转换为列表仍然是非常有用的。
2. 通过包装转换
ArrayList 本质上是封装了数组的 List 接口实现。因此,将一个数组封装为列表最直接的方式就是使用 Kotlin 提供的 asList()
方法。
val array = intArrayOf(1, 2, 3, 4)
val list = array.asList()
assertEquals(listOf(1, 2, 3, 4), list)
对于对象数组,asList()
会调用 Java 的 Arrays.asList()
;对于基本类型数组,则会返回一个继承自 AbstractList
的实现类。
⚠️ 注意:返回的列表是基于原始数组的“视图”,也就是说,数组内容的修改会反映在列表中:
array[0] = 0
assertEquals(listOf(0, 2, 3, 4), list)
✅ 优点:这种转换方式的时间复杂度和空间复杂度都是 *O(1)*,因为它没有复制数据。
3. 通过复制转换
如果我们希望得到一个完全独立于原数组的列表,就需要进行复制操作。Kotlin 提供了多种复制转换的方式,支持生成不可变或可变的列表。
3.1 使用 toCollection
方法
Array.toCollection()
是 Kotlin 提供的一个扩展函数,它接受一个 MutableCollection
参数,并将数组元素添加进去。
val myList = givenArray.toCollection(ArrayList())
assertThat(myList).isEqualTo(expectedList)
这个方法也适合将数组元素追加到已有的可变集合中:
val existingList = mutableListOf("I have an element already.")
val appendedList = givenArray.toCollection(existingList)
assertThat(appendedList).isEqualTo(mutableListOf("I have an element already.", *givenArray))
⚠️ 注意:该方法返回的是我们传入的那个 MutableCollection
实例,所以它是可变的。
3.2 使用 toList
和 toMutableList
方法
更常见的做法是使用 toList()
和 toMutableList()
:
val array = intArrayOf(1, 2, 3, 4)
val list = array.toList()
assertEquals(listOf(1, 2, 3, 4), list)
如果需要后续修改列表内容,使用 toMutableList()
:
val array = intArrayOf(1, 2, 3, 4)
val mutable = array.toMutableList()
assertEquals(listOf(1, 2, 3, 4), mutable)
mutable.add(5)
assertEquals(listOf(1, 2, 3, 4, 5), mutable)
3.3 使用 listOf
和 mutableListOf
+ 展开操作符
Kotlin 的 listOf()
和 mutableListOf()
支持可变参数(vararg),我们可以配合展开操作符 *
将数组解包后传入:
val myList = listOf(*givenArray)
assertThat(myList).isEqualTo(expectedList)
如果需要可变列表,只需换成 mutableListOf(*givenArray)
即可。
3.4 转换后的列表与原数组的关系
所有复制转换方式都会创建一个新的列表,原数组和列表之间不再有关联。因此,修改数组内容不会影响已转换的列表:
array[0] = 0
assertEquals(listOf(1, 2, 3, 4), list) // 列表不会改变
✅ 时间复杂度:复制操作的时间和空间复杂度都是 *O(n)*,因为要逐个复制数组元素。
4. 总结
在 Kotlin 中,有多种方式可以将数组转换为列表:
方法 | 是否可变 | 是否共享数据 | 时间复杂度 |
---|---|---|---|
asList() |
否(取决于原始数组) | ✅ 是 | O(1) |
toCollection() |
✅ 是 | ✅ 是 | O(n) |
toList() / toMutableList() |
✅ 可选 | ❌ 否 | O(n) |
listOf(*array) / mutableListOf(*array) |
✅ 可选 | ❌ 否 | O(n) |
- 如果只是需要一个临时的列表视图,并且不需要修改,推荐使用
asList()
。 - 如果需要独立副本,推荐使用
toList()
或toMutableList()
。 - 若已有可变集合,可使用
toCollection()
追加数据。
完整的示例代码可以在 GitHub 仓库 中找到。