Kotlin 中的数组采用 Array<T> 类定义,抛弃了类 C 语言中 “元素类型[]”的定义方式。下面我们详细讲讲如何在 Kotlin 中使用数组:

1. 创建一个数组

Array<T> 类有两个构造方法:

class Array<T> private constructor() { //私有的 Array<T>() 方法,构造一个空数组
 public inline constructor(size: Int, init: (Int) -> T) //构造使用 init 函数计算元素值的数组}

但一般创建数组时不会使用 Array 类的构造函数,我们需要分三种情况创建数组:

  1. 创建已知所有元素的数组:

    如果我们需要把一组已知的数据放在一个新建的数组里,一般使用 kotlin.arrayOf() 函数。先看一下它的定义:

    // kotlin.Library.ktpublic inline fun <reified @PureReifiable T> arrayOf(vararg elements: T): Array<T>

    其他的东西我们先不管,从这里看到:arrayOf() 参数接收数量不定的 T 类型的元素,并使用它们创建一个数组,然后返回这个数组。我们看下例子:

    val a = arrayOf("Hello", "world")// a = ["Hello", "world"]

    这里,arrayOf() 函数创建了一个 Array<String> 对象,包含两个元素 "Hello","world",并将它赋给变量 a。

    如果我们想像 Java 中那样创建一个长度指定,每个值都是 null 的数组,就要用 kotlin.arrayOfNulls() 函数:

    // kotlin.Library.ktpublic fun <reified @PureReifiable T> arrayOfNulls(size: Int): Array<T?>

    它可以接收一个指定的数组长度,返回一个长度指定、所有值都是 null 的数组:

    var nullArray: Array<String?> = arrayOfNulls(2)// a = [null, null]

    如果我们想依照一定的规律创建一个数组,这时候就要用上构造函数了。比如,我们想创建一个长度为 10 的 Int 类型数组,包含从 1 到 10 的平方,我们可以这样写:

    val squares = Array<Int>(10, { i -> (i+1)*(i+1) })// squares = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

    构造函数的第一个参数是数组的长度,这里指定数组的长度是 10;后面是一个 Lambda 表达式,是指定每个元素值的方法,其中的 i 指元素的索引值。

  2. 创建一个空数组

    如果我们需要一个空的数组,Kotlin 提供了 kotlin.ArrayIntrinsics.emptyArray() 函数:

    public inline fun <reified @PureReifiable T> emptyArray(): Array<T> =
           @Suppress("UNCHECKED_CAST")
           (arrayOfNulls<T>(0) as Array<T>)

    可以看到,emptyArray() 函数是创建一个长度为 0 的 null 数组,然后将它强制转换为指定类型的数组。所以我们可以用 arrayOfNulls<T>(0) 替代 emptyArray() 函数:

    //因为 emptyArray() 函数需要转换为特定的数组类型,所以定义变量需要指定数组类型,否则出现编译错误val emptyArray1: Array<String?> = emptyArray()//也可以写成 val emptyArray2: Array<String?> = arrayOfNulls(0),这里是类型推断val emptyArray2 = arrayOfNulls<String?>(0)println(Arrays.equals(emptyArray1, emptyArray2)) // 输出 true

  3. 创建基本类型数组

    Kotlin 对于基本类型数组有特殊的优化,建议在涉及到基本类型的数组时使用下面列出的类,而不使用 Array 类。

    比如,对于 Int 类型数组,建议使用 IntArray 类替代 Array<Int> 类:

    val intArray = intArrayOf(1, 2, 3)// intArray = [1, 2, 3]val arrayOfInt = arrayOf(1, 2, 3)// arrayOfInt = [1, 2, 3]

    需要注意的一点是,IntArray 类并不是 Array 类的子类,所以上面两个数组并不是相同的对象:

    val isSame = Arrays.equals(intArray, arrayOfInt)// 编译错误,不同类型的数组

    对于其他基本数据类型,也有同样的数组类,它们有与 Array 类一样的操作方式。