Kotlin 语言参考文档 中文版 Help

数组

数组是一种数据结构, 其中包含固定数量的值, 所有的值为同一个类型, 或这个类型的子类型. Kotlin 中最常见的数组类型是对象类型的数组, 使用 Array 类表达.

什么时候使用数组

当你需要满足某些特殊的低层级要求时, 可以在 Kotlin 中使用数组. 例如, 如果你的性能需求超过了通常的应用程序的需求, 或者需要构建自定义数据结构的情况. 如果你没有这种类型的限制, 请使用 集合(Collection).

集合与数组相比, 有以下优点:

  • 集合是只读的, 因此给了你更多的控制权, 使你能够编写意图清晰的, 更加健壮的代码.

  • 更容易对集合添加或删除元素. 与此相反, 数组的大小是固定的. 要对数组添加或删除元素, 只能每次创建新的数组, 这是非常效率低下的:

    fun main() { //sampleStart var riversArray = arrayOf("Nile", "Amazon", "Yangtze") // 使用 += 赋值操作创建新的 riversArray, // 复制原来的元素, 并添加 "Mississippi" riversArray += "Mississippi" println(riversArray.joinToString()) // 输出结果为 Nile, Amazon, Yangtze, Mississippi //sampleEnd }
  • 你可以使用相等操作符(==) 来检查两个集合是否结构相等(Structurally Equal). 但不能对数组使用这个操作符. 相反, 你需要使用特殊的函数, 详情请参见 比较数组.

关于集合, 详情请参见 集合概述.

创建数组

在 Kotlin 中要创建数组, 你可以使用:

下面的示例使用 arrayOf() 函数, 并将数组元素的值传递给它:

fun main() { //sampleStart // 使用元素值 [1, 2, 3] 创建数组 val simpleArray = arrayOf(1, 2, 3) println(simpleArray.joinToString()) // 输出结果为 1, 2, 3 //sampleEnd }

下面的示例使用 arrayOfNulls() 函数创建指定大小的数组, 并使用 null 元素填充数组:

fun main() { //sampleStart // 使用元素值 [null, null, null] 创建数组 val nullArray: Array<Int?> = arrayOfNulls(3) println(nullArray.joinToString()) // 输出结果为 null, null, null //sampleEnd }

下面的示例使用 emptyArray() 函数创建空数组:

var exampleArray = emptyArray<String>()

Array 构造器的参数是, 数组大小, 以及一个函数, 这个函数对指定的数组下标返回对应的元素值:

fun main() { //sampleStart // 创建一个 Array<Int>, 初始化为 0 值: [0, 0, 0] val initArray = Array<Int>(3) { 0 } println(initArray.joinToString()) // 输出结果为 0, 0, 0 // 创建一个 Array<String>, 初始化为 ["0", "1", "4", "9", "16"] val asc = Array(5) { i -> (i * i).toString() } asc.forEach { print(it) } // 输出结果为 014916 //sampleEnd }

嵌套的数组

数组可以相互嵌套, 创建多维数组:

fun main() { //sampleStart // 创建一个 2 维数组 val twoDArray = Array(2) { Array<Int>(2) { 0 } } println(twoDArray.contentDeepToString()) // 输出结果为 [[0, 0], [0, 0]] // 创建一个 3 维数组 val threeDArray = Array(3) { Array(3) { Array<Int>(3) { 0 } } } println(threeDArray.contentDeepToString()) // 输出结果为 [[[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]]] //sampleEnd }

访问和修改元素

数组永远是可以修改的. 要访问和修改数组中的元素, 请使用 下标访问操作符[]:

fun main() { //sampleStart val simpleArray = arrayOf(1, 2, 3) val twoDArray = Array(2) { Array<Int>(2) { 0 } } // 访问并修改元素 simpleArray[0] = 10 twoDArray[0][0] = 2 // 输出修改后的元素 println(simpleArray[0].toString()) // 输出结果为 10 println(twoDArray[0][0].toString()) // 输出结果为 2 //sampleEnd }

Kotlin 中的数组是 不可变的(invariant). 这意味着 Kotlin 不允许你将一个 Array<String> 赋值给一个 Array<Any>, 以防止发生运行时错误. 相反, 你可以使用 Array<out Any>. 更多详情请参见, 类型投射.

使用数组

在 Kotlin 中, 你可以使用数组, 向一个函数传递不定数量的参数, 或对数组元素本身执行操作. 例如, 比较数组, 变换数组内容, 或转换为集合.

向一个函数传递不定数量的参数

在 Kotlin 中, 你可以通过 vararg 参数, 向一个函数传递不定数量的参数. 如果你不能预先知道参数的数量, 这个功能是很有用的, 例如格式化消息, 或者创建 SQL 查询的情况.

要向一个函数传递一个数组, 其中包含不定数量的参数, 请使用 展开(spread) 操作符 (*). 展开操作符会将数组的每个元素作为独立的参数传递给指定的函数:

fun main() { val lettersArray = arrayOf("c", "d") printAllStrings("a", "b", *lettersArray) // 输出结果为 abcd } fun printAllStrings(vararg strings: String) { for (string in strings) { print(string) } }

更多详情请参见 不定数量参数(varargs).

比较数组

要比较两个数组是否包含相同的元素, 并且顺序也相同, 请使用 .contentEquals().contentDeepEquals() 函数:

fun main() { //sampleStart val simpleArray = arrayOf(1, 2, 3) val anotherArray = arrayOf(1, 2, 3) // 比较数组内容 println(simpleArray.contentEquals(anotherArray)) // 输出结果为 true // 使用中缀标记法(Infix notation), 在一个元素发生变化之后, 再次比较数组内容 simpleArray[0] = 10 println(simpleArray contentEquals anotherArray) // 输出结果为 false //sampleEnd }

变换数组

Kotlin 有很多有用的函数, 可以对数组进行变换. 这篇文档重点介绍少数几个函数, 但并不是完整的功能列表. 关于所有函数的完整列表, 请参见我们的 API 参考文档.

求和

要得到一个数组中所有元素的和, 请使用 .sum() 函数:

fun main() { //sampleStart val sumArray = arrayOf(1, 2, 3) // 对数组元素求和 println(sumArray.sum()) // 输出结果为 6 //sampleEnd }

随机打乱

要随机打乱数组中的元素, 请使用 .shuffle() 函数:

fun main() { //sampleStart val simpleArray = arrayOf(1, 2, 3) // 随机打乱元素 [3, 2, 1] simpleArray.shuffle() println(simpleArray.joinToString()) // 再次随机打乱元素 [2, 3, 1] simpleArray.shuffle() println(simpleArray.joinToString()) //sampleEnd }

将数组转换为集合

如果你同时使用不同的 API, 其中一些使用数组, 另一些使用集合, 那么你可以将数组转换为 集合, 也可以反过来将集合转换为数组.

转换为 List 或 Set

要将数组转换为 ListSet, 请使用 .toList().toSet() 函数.

fun main() { //sampleStart val simpleArray = arrayOf("a", "b", "c", "c") // 转换为 Set println(simpleArray.toSet()) // 输出结果为 [a, b, c] // 转换为 List println(simpleArray.toList()) // 输出结果为 [a, b, c, c] //sampleEnd }

转换为 Map

要将数组转换为 Map, 请使用 .toMap() 函数.

只有元素类型为 Pair<K,V> 的数组能够转换为 Map. Pair 实例的第 1 个值成为键(key), 第 2 个值成为值(value). 下面的示例使用 中缀标记法(Infix notation) 来调用 to 函数, 创建 Pair 的元祖:

fun main() { //sampleStart val pairArray = arrayOf("apple" to 120, "banana" to 150, "cherry" to 90, "apple" to 140) // 转换为 Map // 键(key)是水果, 值(value)是它们的卡路里数量 // 注意, 键必须是唯一的, 因此最后一个 "apple" 的值会覆盖第一个的值 println(pairArray.toMap()) // 输出结果为 {apple=140, banana=150, cherry=90} //sampleEnd }

基本类型(Primitive Type)数组

如果你使用 Array 类来存储基本类型(Primitive Type), 这些元素值会被装箱为对象. 另一种选择是, 你可以使用基本类型数组, 它可以让你在数组中存储基本类型, 而不会发生装箱操作导致的性能损失副作用:

基本类型数组

相当于 Java 中的类型

BooleanArray

boolean[]

ByteArray

byte[]

CharArray

char[]

DoubleArray

double[]

FloatArray

float[]

IntArray

int[]

LongArray

long[]

ShortArray

short[]

这些类与 Array 类没有继承关系, 但它们有相同的一组函数和属性.

下面的示例创建一个 IntArray 类的实例:

fun main() { //sampleStart // 创建一个数组, 元素类型为 Int, 大小为 5, 元素值为 0 val exampleArray = IntArray(5) println(exampleArray.joinToString()) // 输出结果为 0, 0, 0, 0, 0 //sampleEnd }

下一步做什么?

  • 为什么对大多数使用场景我们推荐使用集合, 请阅读我们的 集合概述.

  • 学习其他 基本类型.

  • 如果你是 Java 开发者, 请阅读我们的 Java 到 Kotlin 迁移向导, 关于 集合 的部分.

最终更新: 2024/10/17