iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 11
0
Software Development

新手也能懂的 Kotlin Collection 賞玩門道系列 第 11

第十一天:Collection 操作之取值

在前面幾章的內容,我們都著重在 Kotlin Collection 各別的特點、宣告語法以及呼叫 Collection 的屬性及方法。接下來要開始深入了解 Collection 的各種操作技巧,在這篇文章裡,先從最常用的讀取開始。

以 index 取得資料

Collection 類別裡除了 Set 以外,其他類別都有 index。所以要取得 Collection 裡的資料,可以很方便的使用 [] 加上 index 取得。

val arrayOfNumbers = arrayOf(2, 3, 5, 6, 10)
println(arrayOfNumbers[0]) // 2

以中括號取資料的這種方式簡單直覺,不過假如想要用 method() 這種比較符合英文語意的方式來取得資料的話,可以用 get() 加上 index 取得。

val arrayOfNumbers = arrayOf(2, 3, 5, 6, 10)
println(arrayOfNumbers.get(0)) // 2

Set 因為是無序且沒有 index,所以無法用以上這兩種方式來取得資料。不過 Kotlin 提供另一種 elementAt() 的 method 供使用,使用起來跟 get() 雷同。除了 Set 以外,其他 Collection 類別也有這個 method。

val setOfNumbers = setOf(1, 3, 5, 7, 9)
println(setOfNumbers.elementAt(0)) // 1 

處理取值例外

使用 index 來取值很方便,但要特別注意的是,若嘗試以不存在的 index 抓取元素,則會觸發 ArrayIndexOutOfBoundsExceptionIndexOutOfBoundsException 等例外狀況。若要妥善地處理這些情境的話,Collection 提供兩種方式:

  1. 使用 getOrNull()elementAtOrNull()

    val listOfNames = listOf("Tom", "John", "Allen", "Sean")
    val secondPerson = listOfNames.getOrNull(4) ?: "Unknown Person"   
    

    使用 OrNull 結尾的 method,當 index 超過邊界時會回傳 null,這時可以搭配 Elvis Operator 來補上預設值。

  2. 使用 getOrElse()elementAtOrElse()

    val listOfNames = listOf("Tom", "John", "Allen", "Sean")
    val secondPerson = listOfNames.getOrElse(4) { "Unknown Person" }   
    

    使用 OrElse 結尾的 method,則可以傳入一個 Lambda 當參數,讓 Lambda 裡的邏輯來決定如何產生預設值,讓例外處理可以有更大的彈性。

方便法門

為了讓程式更有語意,Collection 也將常用的取值操作做成 method 方便大家使用,比方說取得第一個值的 first()、最後一個值的 last() 以及隨機取值的 random()

val listOfNumbers = listOf(2, 3, 5, 6, 7)
val first = listOfNumbers.first() // 2
val last = listOfNumbers.last() // 7
val random = listOfNumbers.random() // 從 2, 3, 5, 6, 7 隨機取出一個

考量到有可能取不到對應的值,因此以上所有 method 都有對應一個 OrNull 的版本:

val listOfNumbers = listOf(2, 3, 5, 6, 7)
val first = listOfNumbers.firstOrNull() // 2
val last = listOfNumbers.lastOrNull() // 7
val random = listOfNumbers.randomOrNull() // 從 2, 3, 5, 6, 7 隨機取出一個

設定取值條件

以上的幾個 method,以 first() 為例,其本意是「回傳第一個滿足條件的元素不然就拋 NoSuchElementException,假如不給條件的話,就回傳第一個元素」。意思就是說,first() 在標準函式庫裡用 method overload 的方式定義了兩種用法,一種就是如上不給參數的方式使用,回傳 Collection 裡的第一個 method、另一種就是傳入一個 Lambda 來決定取值條件。以 Lambda 當做參數傳入的設計,讓 Collection 操作有點極大的彈性。

val numbers = listOf("one", "two", "three", "four", "five", "six")
val first = numbers.first { it.length > 3 } // three
val last = numbers.last { it.startsWith("f") } // five 

表格整理

以上快速地介紹如何從 Collection 裡取得資料,不過根據類別的不同,可以使用的方式也不同,以下用表格快速整理本篇文章裡提到的所有方式:

行為 Array List Set Map
[index] index 越界會拋出異常 v v x v
get() index 越界會拋出異常 v v x v
elementAt() index 越界會拋出異常 v v v x
getOrNull() index 越界回傳 null v v x x
elementAtOrNull() index 越界回傳 null v v v x
getOrElse() index 越界可以用 Lambda 給預設值 v v x v
elementAtOrElse() index 越界可以用 Lambda 給預設值 v v v x
first() 取值失敗會拋出異常 v v v x
firstOrNull() 取值失敗回傳 null v v v x
last() 取值失敗會拋出異常 v v v x
lastOrNull() 取值失敗回傳 null v v v x
random() 取值失敗會拋出異常 v v v x
randomOrNull() 取值失敗回傳 null v v v x

參考資料


上一篇
第十天:Kotlin Collection 之 Map
下一篇
第十二天:Collection 操作之修改
系列文
新手也能懂的 Kotlin Collection 賞玩門道31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言