區間(Range)
區間是一個數學上的概念,表示範圍。
區間的宣告Kotlin 中可以使用 .. 或 until 來宣告區間:
val range: IntRange = 0..1024 // 閉區間[0,1024],包括1024val rangeExclusive: IntRange = 0 until 1024 // 半開區間[0,1024),不包括1024val emptyRange: IntRange = 0..-1 // 空區間[]
其實這裡的 .. 運算子對應的是 Int 類中的一個 rangeTo() 方法:
/** Creates a range from this value to the specified [other] value. */public operator fun rangeTo(other: Byte): IntRange/** Creates a range from this value to the specified [other] value. */public operator fun rangeTo(other: Short): IntRange/** Creates a range from this value to the specified [other] value. */public operator fun rangeTo(other: Int): IntRange/** Creates a range from this value to the specified [other] value. */public operator fun rangeTo(other: Long): LongRange
區間常用操作判斷某個元素是否在區間內:
println(range.contains(50)) // trueprintln(500 in range) // true
這裡的 in 關鍵字對應的就是 IntRange 類中的 contains() 方法,因此上面的兩行程式碼實質上是一樣的。
判斷區間是否為空:
println(rangeExclusive.isEmpty()) // falseprintln(emptyRange.isEmpty()) // true
對區間進行遍歷:
// 輸出:0, 1, 2, 3 ..... 1020, 1021, 1022, 1023,for (i in rangeExclusive) { print("$i, ")}
這裡的 in 跟 for 配合使用,就可以實現區間的遍歷效果。
區間的型別所有的區間都是 ClosedRange 的子類,IntRange 最常用。透過原始碼不難發現,除了 IntRange ,ClosedRange 的子類還有 LongRange、CharRange 等等。
以 CharRange 為例,我們還可以寫出 26 個大小寫字母的區間:
// a b c d e f g h i j k l m n o p q r s t u v w x y zval lowerRange: CharRange = 'a'..'z'// A B C D E F G H I J K L M N O P Q R S T U V W X Y Zval upperRange: CharRange = 'A'..'Z'
陣列(Array)
陣列(Array)跟數(Number)沒有關係,它指的是一系列物件。
建立陣列建立陣列一般有 2 種方式:
使用 Array 類建立陣列使用庫函式 arrayOfXXX() 建立陣列使用 Array 類建立陣列先看看 Array 的建構函式:
public class Array<T> { /** * Creates a new array with the specified [size], where each element is calculated by calling the specified * [init] function. The [init] function returns an array element given its index. */ public inline constructor(size: Int, init: (Int) -> T) ...}
使用 Array 建立陣列,需要指定元素型別(一般情況下可以省略),有 2 個必傳引數,分別是陣列長度 size,和元素初始化函式 init。
val array = Array<String>(5) { index -> "No.$index" }println(array.size) // 5for (str in array) { // No.0 No.1 No.2 No.3 No.4 print("$str ")}
當函式引數是最後一個形參時,可以把它寫到括號外,這是 Kotlin 中的 lambda 寫法,當然,你也可以不用 lambda 寫法,就寫在括號內:val array = Array<String>(5, { index -> "No.$index" }),關於 lambda 的相關知識在這裡暫不細說。
使用庫函式 arrayOfXXX() 建立陣列直接使用 Array 建立陣列會稍稍有點麻煩,要指定個數,又要傳入初始化函式, 而實際開發中,我們希望有更方便的寫法來提高工作效率,Kotlin 就為此就提供了一系列建立陣列的庫函式 arrayOfXXX() :
val arrayOfString: Array<String> = arrayOf("我", "是", "LQR")val arrayOfHuman: Array<Human> = arrayOf(Boy("溫和", "英俊", "渾厚"), Girl("溫柔", "甜美", "動人"))val arrayOfInt: IntArray = intArrayOf(1, 3, 5, 7)val arrayOfChar: CharArray = charArrayOf('H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd')
要注意,用於存放 String 型別或自定義型別的物件陣列 的建立使用的是 arrayOf(),而基本資料型別陣列的建立則有專門的庫函式,如:intArrayOf()、charArrayOf() 等。intArrayOf()、charArrayOf() 等庫函式是 Kotlin 為了避免基本資料裝箱折箱的開銷而專門創造出來的,比如:intArrayOf(1, 3, 5, 7) 創建出來的陣列是 IntArray 型別,對應到 Java 中是 int[] ,而 arrayOf(1, 2, 3, 4) 創建出來的陣列是 Array<Int> 型別,對應 Java 中是 Integer[]。
基本資料型別陣列為了避免不必要的裝箱和拆箱,基本資料型別的陣列是定製的:
JavaKotlinint[]IntArrayshort[]ShortArraylong[]LongArrayfloat[]FloatArraydouble[]DoubleArraychar[]CharArray
注意:IntArray 和 Array<Int> 是完全不同的型別,無法直接相互轉換!原話:Kotlin 也有無裝箱開銷的專門的類來表示原生型別陣列: ByteArray、 ShortArray、IntArray 等等。這些類與 Array 並沒有繼承關係,但是它們有同樣的方法屬性集。
陣列常用操作可以使用 .size 獲取陣列長度,使用 for-in 遍歷陣列:
println(arrayOfInt.size) // 4for (int in arrayOfInt) { // 1 3 5 7 print("$int ")}
Array 定義了 get 與 set 函式(按照運算子過載約定這會轉變為 []),因此我們可以透過 [] 來獲取或修改陣列中的元素:
println(arrayOfHuman[1]) // 我是性格溫柔,長相甜美,聲音動人的人arrayOfHuman[1] = Boy("溫和1", "英俊1", "渾厚1")println(arrayOfHuman[1]) // 我是性格溫和1,長相英俊1,聲音渾厚1的人
注意:自定義型別物件使用 println() 預設輸出的是物件地址資訊,如:com.charylin.kotlinlearn.Boy@7440e464 ,需要重寫類的 toString() 方法來修改輸出日誌內容。
CharArray 提供了 joinToString() 方法,用於將字元陣列拼接成字串,預設以 , 作為拼接符:
println(arrayOfChar.joinToString()) // H, e, l, l, o, W, o, r, l, dprintln(arrayOfChar.joinToString("")) // HelloWorld
可以使用 slice() 方法對陣列進行切片:
println(arrayOfInt.slice(1..2)) // [3, 5]