数组
数组是一种数据结构, 包含固定数量的值, 值都是相同类型, 或者是它的子类型. 数组元素按顺序排列, 通过下标访问.
Kotlin 提供了 Array<T> 类, 和 基本类型数组.
什么时候使用数组
当你需要与 Java API 互操作, 或满足底层需求时, 请使用数组. 例如, 当性能要求超出普通应用程序的需要时, 或者需要构建自定义数据结构时.
对于大多数使用场景, 请优先使用 集合.
功能 | 数组 | 集合 |
|---|---|---|
大小 | 固定 | 取决于类型 |
只读形式 | 没有, 始终可修改 | 有 ( |
添加和删除元素 | 不直接支持. | 支持 (可变集合) |
使用 | 不支持, 只比较引用. | 支持 |
基本类型值 | 基本类型数组可以存储值, 不装箱 | 通常会装箱 |
Java 互操作性 | 映射为 | 映射为 |
函数式过滤和变换操作 | 支持的操作有限 | 支持的操作丰富 |
了解如何 将数组转换为集合.
创建数组
要创建数组, 可以选择使用:
arrayOf(),arrayOfNulls(), 或emptyArray()函数.Array构造器.
创建包含元素值的数组
要使用一组已知的值创建指定类型的数组, 请使用 arrayOf() 函数. Kotlin 会自动推断类型:
创建空数组
要创建没有元素的数组, 请使用 emptyArray() 函数. 可以在赋值语句的左侧或右侧指定元素类型:
了解如何 向数组添加元素.
创建 null 值的数组
要创建指定大小且由 null 元素填充的数组, 请使用 arrayOfNulls() 函数:
使用 Array 构造器
Array 构造器接收的参数是, 数组大小, 以及一个函数, 这个函数返回数组元素值:
创建嵌套数组
要创建嵌套数组, 或者叫多维数组, 请使用数组的数组. 嵌套数组不需要具有相同的类型, 或相同的大小.
创建基本类型数组
如果使用 Array 类存储基本类型的值, 编译器会将这些值装箱为对象. 为了避免装箱的开销, 可以使用专门的基本类型数组. 它们不是 Array<T> 类的子类, 但提供类似的函数和属性.
Kotlin 类型 | 等同的 Java 类型 |
|---|---|
| |
| |
| |
| |
| |
| |
| |
|
要创建基本类型数组, 可以选择使用以下方式之一:
构造函数:
fun main() { //sampleStart // 创建大小为 5 的 Int 数组, 元素初始值为 0 val primitiveTypeArray = IntArray(5) println(primitiveTypeArray.joinToString()) // 输出结果为: 0, 0, 0, 0, 0 // 创建 Int 数组, 并提供初始化函数 val squares = IntArray(5) { i -> i * i } println(squares.joinToString()) // 输出结果为: 0, 1, 4, 9, 16 //sampleEnd }工厂函数:
fun main() { //sampleStart // 创建包含 5 个元素的 Int 数组 val numbers = intArrayOf(1, 2, 3, 4, 5) println(numbers.joinToString()) // 输出结果为: 1, 2, 3, 4, 5 // 创建包含 3 个元素的 Char 数组 val characters = charArrayOf('K', 't', 'l') println(characters.joinToString()) // 输出结果为: K, t, l // 创建包含 3 个元素的 Double 数组 val doubles = doubleArrayOf(0.22, 4.16, 0.5) println(doubles.joinToString()) // 输出结果为: 0.22, 4.16, 0.5 //sampleEnd }
使用数组
数组支持很多与集合相同的操作, 包括遍历, 搜索, 排序, 以及变换. 在 Kotlin 中, 你可以使用数组向函数传递不定数量的参数, 或对数组本身执行操作. 下表列出了最常用的属性和函数:
成员 | 返回值 |
|---|---|
元素数量 | |
有效的下标范围 | |
最后一个有效下标 | |
第一个和最后一个元素 | |
数组为空返回 | |
数组包含该元素时返回 |
本节介绍一些最常用的操作.
访问和修改元素
要访问和修改数组中的元素, 请使用 下标访问操作符 ([]):
还可以使用 fill(element, fromIndex, toIndex) 函数, 就地替换指定范围内的元素. fromIndex 包含在范围内, toIndex 不包含在范围内:
在 Kotlin 中, 数组是 类型不可变的(Invariant). 也就是说, Array<String> 不是 Array<Any> 的子类型. 这种机制可以防止潜在的运行时类型错误. 要表示协变(Covariance), 请使用 Array<out Any> 类型投影:
添加和删除元素
由于数组大小是固定的, 因此不支持 .add() 和 .remove() 函数. 要进行这样的操作, 需要创建新数组. 可以选择使用以下方式之一:
使用
.copyOf()函数:fun main() { //sampleStart var arr = intArrayOf(0, 1, 2) arr = arr.copyOf(arr.size + 1) println(arr.joinToString()) // 输出结果为: 0, 1, 2, 0 arr[arr.lastIndex] = 3 println(arr.joinToString()) // 输出结果为: 0, 1, 2, 3 //sampleEnd }使用
+或+=操作符:fun main() { //sampleStart var arr = intArrayOf(0, 1, 2) arr += 3 println(arr.joinToString()) // 输出结果为: 0, 1, 2, 3 arr = arr + intArrayOf(4, 5) println(arr.joinToString()) // 输出结果为: 0, 1, 2, 3, 4, 5 //sampleEnd }
比较数组
要比较两个数组是否包含相同的元素, 并且顺序也相同, 请使用 .contentEquals() 和 .contentDeepEquals() 函数:
变换数组
Kotlin 有很多有用的函数, 可以对数组进行变换. 本节重点介绍其中几个函数. 关于所有函数的完整列表, 请参见我们的 API 参考文档.
求和
要得到一个数组中所有元素的和, 请使用 .sum() 函数:
排序和随机打乱
可以使用 .sort() 函数, 对数组元素按自然顺序排序, 或使用 .shuffle() 函数, 随机打乱元素:
要在不修改原始数组的情况下获得排序后的新数组, 请改用 .sortedArray() 函数.
向函数传递不定数量的参数
在 Kotlin 中, 可以通过 vararg 参数, 向函数传递不定数量的参数. 当你无法预先确定参数数量时, 例如格式化消息时, 或创建 SQL 查询时, 这个功能很有用.
要将包含不定数量参数的数组传递给函数, 请使用 展开操作符 (*). 展开操作符将数组中的每个元素作为单独的参数传给函数:
详情请参见 不定数量参数(varargs).
转换为集合
如果需要使用不同的 API, 其中一些使用数组, 另一些使用集合, 可以在数组和集合之间转换. 要进行转换, 请使用 .toList(), .toSet(), 以及 .toMap() 函数. 这些函数会将数组内容复制到独立的集合中. 数组的后续变化不会反映到集合中.
转换为 List 或 Set
要将数组转换为 List 或 Set, 请使用 .toList() 和 .toSet() 函数:
除非完全确定原始数组不会被修改, 也不会在其他地方共用, 否则不要使用 .asList() 和相关的 as* 函数. 这些函数会包装原始数组, 而不是复制数组. 因此, 数组的变化会反映到列表中, 反过来也是如此.
转换为 Map
要将数组转换为 Map, 请使用 .toMap() 函数.
只有元素类型为 Pair<K,V> 的数组, 才能转换为 Map. Pair 实例的第 1 个值成为键, 第 2 个值成为值. 如果同一个键出现多次, 将使用最后一个值.
下面的示例使用 中缀标记法 调用 .to 函数, 创建 Pair:
下一步做什么?
为什么对大多数使用场景我们推荐使用集合, 请阅读我们的 集合概述.
学习其他 基本类型.
如果你是 Java 开发者, 请阅读我们的 Java 到 Kotlin 迁移向导, 关于集合的部分.