Kotlin 中的 List 跟 Java 有點不一樣,分為以下兩種
但跟一般資料結構的 List 概念一樣
只能讀取,不能修改內容
創造方式如下,使用 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()
建立一個沒有 null 的 list
val listNotNulls = listOfNotNull("tim", "andy", "ann")
像下面的做法,很特別,之前有在 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 取值的使用方式跟 Array 一樣,一樣取超出範圍會有 Exception
println(list[2]) // ann
println(list.get(2)) // ann
// println(list[3]) // Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
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() 如果存在,回傳 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")
}
可讀可修改的 list,底層其實是 Java 的 ArrayList,所以是一個可變動大小的 List
創造方法:
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)
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)
跟之前 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")
}
不論 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")
Collection 都有 emptyXXX
在我們認為結果是空的時候,可以直接使用
fun returnEmpty(): List<String> {
val result: List<String>? = null
if (result != null) return result
return emptyList()
}
當然也可以使用我們在 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>()
println(listOf("b", "a", "c").sortedDescending()) // [c, b, a] 降序
println(listOf("b", "a", "c").sortedBy { it }) // [a, b, c] 升序
list.toSet() 也是一樣的效果,只是還要再轉回來 list
println(listOf("name1", "name2", "name1").distinct())
其實去看 bytecode,distinct() 也是這樣做實作的
以上就是今天的內容!謝謝大家!
今日練習的程式在這: 請點我