数组
数组用于保存固定数量的相同类型或其子类型的值。Kotlin 中最常见的数组类型是对象类型数组,由 Array
类表示。
如果在对象类型数组中使用基本类型,这会影响性能,因为您的基本类型会被装箱为对象。为了避免装箱开销,请改用基本类型数组。
何时使用数组
当有需要满足的特殊低级需求时,请在 Kotlin 中使用数组。例如,如果有超出常规应用程序需求的性能要求,或者需要构建自定义数据结构。如果没有这些限制,请改用集合。
与数组相比,集合具有以下优势:
-
集合可以是只读的,这为您提供了更多控制权,并允许您编写具有明确意图的健壮代码。
-
可以轻松地从集合中添加或删除元素。相比之下,数组的大小是固定的。从数组中添加或删除元素的唯一方法是每次都创建一个新数组,这非常低效。
-
可以使用相等操作符(
==
)检查集合是否结构相等。不能将此操作符用于数组。相反,必须使用特殊函数。
var riversArray = arrayOf("Nile", "Amazon", "Yangtze")// 使用 += 赋值操作会创建一个新的 riversArray,复制原始元素并添加 Mississippi。
riversArray += "Mississippi"println(riversArray.joinToString()) // Nile, Amazon, Yangtze, Mississippi
创建数组
要在 Kotlin 中创建数组,可以使用:
-
函数,例如
arrayOf()
、arrayOfNulls()
或emptyArray()
。 -
Array
构造函数。
// 创建一个值为 [1, 2, 3] 的数组。
val simpleArray = arrayOf(1, 2, 3)
println(simpleArray.joinToString()) // 1, 2, 3
// 创建一个值为 [null, null, null] 的数组。
val nullArray: Array<Int?> = arrayOfNulls(3)
println(nullArray.joinToString()) // null, null, null
// 创建一个空数组。
var exampleArray = emptyArray<String>()
由于类型推断,可以在赋值的左侧或右侧指定空数组的类型。
var exampleArray = emptyArray<String>()var exampleArray: Array<String> = emptyArray()
Array
构造函数接受数组大小和一个函数,该函数根据索引返回数组元素的值。
// 创建一个初始化为零 [0, 0, 0] 的 Array<Int>。
val initArray = Array<Int>(3) { 0 }
println(initArray.joinToString()) // 0, 0, 0// 创建一个值为 ["0", "1", "4", "9", "16"] 的 Array<String>。
val asc = Array(5) { i -> (i * i).toString() }
asc.forEach { print(it) } // 014916
与大多数编程语言一样,Kotlin 中的索引从 0 开始。
嵌套数组
数组可以相互嵌套以创建多维数组。
// 创建一个二维数组。
val twoDArray = Array(2) { Array<Int>(2) { 0 } }
println(twoDArray.contentDeepToString()) // [ [0, 0], [0, 0] ]// 创建一个三维数组。
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] ]
]
*/
嵌套数组不必是相同的类型或相同的大小。
访问和修改元素
数组元素始终是可变的。要访问和修改数组中的元素,请使用索引访问操作符 []
。
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
Kotlin 中的数组是不变的(invariant)。这意味着 Kotlin 不允许您将 Array<String>
分配给 Array<Any>
以防止可能的运行时失败。相反,您可以使用 Array<out Any>
。
使用数组
在 Kotlin 中,您可以通过使用数组将可变数量的参数传递给函数或对数组本身执行操作。例如,比较数组、转换其内容或将其转换为集合。
将可变数量的参数传递给函数
可以通过 vararg
参数将可变数量的参数传递给函数。这在事先不知道参数数量时非常有用,例如格式化消息或创建 SQL 查询时。
要将包含可变数量参数的数组传递给函数,请使用展开操作符 *
。展开操作符将数组的每个元素作为单独的参数传递给所选函数。
fun main() {val lettersArray = arrayOf("c", "d")printAllStrings("a", "b", *lettersArray) // abcd
}fun printAllStrings(vararg strings: String) {for (string in strings) {print(string)}
}
比较数组
要比较两个数组是否具有相同顺序的相同元素,请使用 contentEquals()
和 contentDeepEquals()
函数。
val simpleArray = arrayOf(1, 2, 3)
val anotherArray = arrayOf(1, 2, 3)// 比较数组内容。
println(simpleArray.contentEquals(anotherArray)) // true// 使用中缀表示法,在更改元素后比较数组内容。
simpleArray[0] = 10
println(simpleArray contentEquals anotherArray) // false
不要使用相等(==
)和不等(!=
)操作符来比较数组的内容。这些操作符检查分配的变量是否指向同一个对象。
转换数组
Kotlin 有许多有用的函数来转换数组。先在这介绍一些。
要返回数组中所有元素的总和,请使用 sum()
函数:
val sumArray = arrayOf(1, 2, 3)// 对数组元素求和。
println(sumArray.sum()) // 6
sum()
函数只能用于数值数据类型的数组,例如 Int
。
要随机打乱数组中的元素,请使用 shuffle()
函数:
val simpleArray = arrayOf(1, 2, 3)// 打乱元素 [3, 2, 1]
simpleArray.shuffle()
println(simpleArray.joinToString())// 再次打乱元素 [2, 3, 1]
simpleArray.shuffle()
println(simpleArray.joinToString())
将数组转换为集合
如果您使用不同的 API,其中一些使用数组,而另一些使用集合,那么您可以将数组转换为集合,反之亦然。
要将数组转换为 List
或 Set
,请使用 toList()
和 toSet()
函数。
val simpleArray = arrayOf("a", "b", "c", "c")// 转换为 Set。
println(simpleArray.toSet()) // [a, b, c]// 转换为 List。
println(simpleArray.toList()) // [a, b, c, c]
要将数组转换为 Map
,请使用 toMap()
函数。
只有 Pair<K,V>
的数组才能转换为 Map
。
Pair
实例的第一个值成为键,第二个值成为值。
此示例使用中缀表示法调用 to
函数来创建 Pair
元组。
val pairArray = arrayOf("apple" to 120, "banana" to 150, "cherry" to 90, "apple" to 140)// 转换为 Map。
// 键是水果,值是它们的卡路里。
// 注意键必须是唯一的,因此 apple 的最新值会覆盖第一个值。
println(pairArray.toMap()) // {apple=140, banana=150, cherry=90}
基本类型数组
如果您将 Array
类与基本值一起使用,这些值会被装箱为对象。
作为替代方案,您可以使用基本类型数组,这些数组允许您在不产生装箱开销的情况下存储基本类型。
基本类型数组 | Java 中的等效类型 |
---|---|
BooleanArray | boolean[] |
CharArray | char[] |
ByteArray | byte[] |
ShortArray | short[] |
IntArray | int[] |
LongArray | long[] |
DoubleArray | double[] |
FloatArray | float[] |
这些类与 Array
类没有继承关系,但它们具有相同的函数和属性集。
此示例创建 IntArray
类的实例:
fun main() {val intArray1 = IntArray(5)val intArray2 = intArrayOf(1, 2, 3)
}
要将基本类型数组转换为对象类型数组,请使用 toTypedArray()
函数。
要将对象类型数组转换为基本类型数组,请使用 toBooleanArray()
、toByteArray()
、toCharArray()
等函数。