iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 19
0
Software Development

Kotlin 島深度之旅 30 天系列 第 19

[Day 19] Kotlin Journey - List

List

Kotlin 中的 List 跟 Java 有點不一樣,分為以下兩種

  • 只可讀的 List
  • 可以修改的 Mutable List

但跟一般資料結構的 List 概念一樣

  • 資料是有序的(有 index)
  • 資料可以重複
  • 可以透過 index 隨機存取資料

不可修改的 List

只能讀取,不能修改內容

listOf()

創造方式如下,使用 listOf()

// 可以明確指定型態
val list:List<String> = listOf("tim", "andy", "ann")

// 也可以直接讓 Kotlin 自行推斷
val list = listOf("tim", "andy", null)

如下例,前面講到不能修改,想要做 list[2] = "jean"list.set(2) = "xxx" (根本沒有 set()方法)是完全不行的。

但針對 list2 是 var 的話,要取代整個 list2 變數是可以的。

    // list[2] = "jean" // 不行!

    var list2 = listOf("tim", "andy", "ann")
    list2 = listOf("1", "2", "3")

listOfNotNull()

也可以使用 listOfNotNull() 建立一個沒有 null 的 list

val listNotNulls = listOfNotNull("tim", "andy", "ann")

List Lambda

像下面的做法,很特別,之前有在 Array 提過一樣的用法, it 會是 index,但這邊的結果會產生一個 大小是 5 的 list [a, b, c, d, e]

val its = List(5) { // it is index
    'a' + it
} // [a, b, c, d, e]
println(its)

這樣則會是 [t0, t1, t2, t3, t4]

val its2 = List(5) {
    "t$it"
} // [t0, t1, t2, t3, t4]
println(its2)

List 取值

List 取值的使用方式跟 Array 一樣,一樣取超出範圍會有 Exception

println(list[2]) // ann
println(list.get(2)) // ann
// println(list[3]) // Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3

getOrElse() getOrNull()

list 還有 getOrElse(), getOrNull() 可以使用

getOrElse() 當取不到值時,會傳最後 lambda 內的值

getOrNull() 當取不到值時,會回傳 null ,這裡還用了貓王運算子,所以會傳回 "no value"

println(list.getOrElse(3) { "no value" }) // no value
println(list.getOrNull(3) ?: "no value") // no value

contains() containsAll()

contains() 如果存在,回傳 true

containsAll(list) 會傳入整個 list,如果都存在,回傳 true

// tim exists
if (list.contains("tim")) {
    println("tim exists")
} else {
    println("tim doesn't exist")
}

// one person doesn't exist
if (list.containsAll(listOf("tim", "jim"))) {
    println("tim, jim exists")
} else {
    println("one person doesn't exist")
}

Mutable List

可讀可修改的 list,底層其實是 Java 的 ArrayList,所以是一個可變動大小的 List

mutableListOf()

創造方法:

val muList = mutableListOf("tim", "andy", "ann")
println(muList.get(0))
println(muList[0])

或用 lambda 也可以建立,跟 List 例子一樣

val itsMu = MutableList(5) {
    'a' + it
} // [a, b, c, d, e]
println(itsMu)

Mutable List 修改刪除

muList.add("Max")
muList.remove("tim")
muList.add(0, "tim")
muList.addAll(listOf("student1", "student2"))
muList.set(0, "timfix")
muList[0] = "tim fix again"

// 移除 "student"
muList.removeIf { it.contains("student") }
println(muList)

Loop

跟之前 Array 介紹的方法都一樣,只是一種是走 for ,另一種是走 forEach lambda 的方式

for (idx in muList.indices) { 
    println(muList[idx])
}

for (d in muList.withIndex()) { 
    println("idx: ${d.index}, value: ${d.value}")
}

muList.forEach {
    println("each name: $it")
}

muList.forEachIndexed { index, name ->
    println("each name: #${index} - $name")
}

deconstruct (解構)

不論 Array, List, Mutable List 都可以做解構,會照順序塞入我們定義的變數

val (num1, _, num3) = arrayOf<Int>(1, 2, 3) // new Integer[]{1, 2, 3};

val (num01, _, num03) = intArrayOf(1, 2, 3) // new int[]{1, 2, 3};

val (name01, _, name02) = list
println("$name01 and $name02")

val (name1, _, name2) = muList
println("$name1 and $name2")

emptyList<型態>()

Collection 都有 emptyXXX

https://ithelp.ithome.com.tw/upload/images/20200928/20129902IPMM35fvTM.png

在我們認為結果是空的時候,可以直接使用

fun returnEmpty(): List<String> {
    val result: List<String>? = null
    if (result != null) return result
    return emptyList()
}

ArrayList

當然也可以使用我們在 Java 中熟悉的 ArrayList,arrayListOf() 是 Kotlin 提供的,當然也可以使用 Java 的方式來宣告一些在 Java 的 Collections 物件

// arrayList
val aryList = arrayListOf(1, 2, 3) // java ArrayList, ArrayList<E> = java.util.ArrayList<E>

// 用傳統方式宣告,一個空的 ArrayList
var result = ArrayList<Int>()

// 用傳統方式宣告,一個空的 LinkedList
var result2 = LinkedList<Int>()

list 的 sort - list.sortedDescending() & list.sortedBy { it }

println(listOf("b", "a", "c").sortedDescending()) // [c, b, a]  降序
println(listOf("b", "a", "c").sortedBy { it }) // [a, b, c]  升序

list.distinct()

list.toSet() 也是一樣的效果,只是還要再轉回來 list

println(listOf("name1", "name2", "name1").distinct())

其實去看 bytecode,distinct() 也是這樣做實作的

https://ithelp.ithome.com.tw/upload/images/20200929/20129902DyPvjj2KeE.png

以上就是今天的內容!謝謝大家!

今日練習的程式在這: 請點我


上一篇
[Day 18] Kotlin Journey - Array (陣列)
下一篇
[Day 20] Kotlin Journey - Set
系列文
Kotlin 島深度之旅 30 天31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言