Kotlin Collections 集合:List, Set, Map

Kotlin 的集合框架建立在 Java 之上,但它在語言層面做出了一個非常重要的區分:唯讀 (Read-only)可變 (Mutable)

這意味著,當你宣告一個 List 時,編譯器會預設它是不可修改的。這大大降低了「意外修改到資料」的風險,讓程式更安全、更容易測試。

集合類型介紹 (Types)

List (串列)

有序 (Ordered)可重複 的集合,透過索引值 (Index) 存取。

// 不可變
val readOnlyList = listOf("Apple", "Banana")
println(readOnlyList[0])

// 可變
val mutableList = mutableListOf("Apple", "Banana")
mutableList.add("Cherry")

Set (集)

無序 (Unordered)不重複 的集合。常用於去重或檢查存在性。

val numbers = setOf(1, 2, 2, 3)
println(numbers) // [1, 2, 3] (自動去除重複)

Map (鍵值對)

儲存 Key-Value 的容器。Key 唯一,Value 可重複。

val map = mapOf(1 to "One", 2 to "Two")
val mutableMap = mutableMapOf(1 to "One")
mutableMap[2] = "Two"

通用操作 (List & Set)

這些操作適用於所有 Iterable (包含 List 和 Set)。注意:對 Set 進行 filter 或 map 操作後,結果通常會變成 List。

forEach (遍歷)

val numbers = listOf(1, 2, 3)
numbers.forEach { println(it) }

filter (過濾) & map (轉換)

val list = listOf(1, 2, 3, 4)

// 過濾偶數
val evens = list.filter { it % 2 == 0 } 

// 數字轉字串
val strings = list.map { "Number $it" }

any, all, none (檢查)

回傳 Boolean。

val hasEven = list.any { it % 2 == 0 } // 是否有偶數?
val allEven = list.all { it % 2 == 0 } // 是否全為偶數?

find (搜尋)

val firstEven = list.find { it % 2 == 0 } // 回傳 2 或 null

List 專屬操作

這些操作依賴於順序,主要用於 List。

get (存取)

除了 list[0],還有安全版本:

val list = listOf("A", "B")
println(list.getOrNull(5)) // null (不會 Crash)

sort (排序)

val numbers = listOf(3, 1, 2)
val sorted = numbers.sorted() // [1, 2, 3]

zip (組合)

將兩個 List 拉鍊在一起。

val names = listOf("Alice", "Bob")
val ages = listOf(18, 20)
val zipped = names.zip(ages) // [(Alice, 18), (Bob, 20)]

Map 專屬操作

Map 的操作邏輯比較不同,通常針對 Key 或 Value 分別處理。

filterKeys & filterValues

只過濾 Key 或只過濾 Value (保持 Map 結構)。

val map = mapOf("A" to 1, "B" to 2, "C" to 3)

// 只留 Key 包含 "A" 的
val filtered = map.filterKeys { it.contains("A") } 

mapKeys & mapValues

只轉換 Key 或只轉換 Value。

// 將所有 Value 乘以 10
val newMap = map.mapValues { it.value * 10 }
// {A=10, B=20, C=30}

getOrPut (可變 Map 專用)

如果 Key 存在就回傳,不存在就放入預設值並回傳。非常實用!

val counts = mutableMapOf<String, Int>()
// 如果 "Apple" 沒出現過,預設給 0
val count = counts.getOrPut("Apple") { 0 }

Set 專屬操作 (集合運算)

數學上的聯集、交集與差集。

val set1 = setOf(1, 2, 3)
val set2 = setOf(2, 3, 4)

// 聯集 (A + B)
println(set1 union set2) // [1, 2, 3, 4]

// 交集 (A 且 B)
println(set1 intersect set2) // [2, 3]

// 差集 (A - B)
println(set1 subtract set2) // [1] (在 A 但不在 B)

其他補充

建立空集合

為了明確型別並避免 null。

val empty = emptyList<String>()

List 與 Array 轉換

Array 是固定長度 (JVM Array),List 是動態長度。

val arr = arrayOf(1, 2).toList()
val list = listOf(1, 2).toTypedArray()

效能優化 (Sequences)

如果集合很大或操作鍊很長,請改用 Sequence 以獲得更好的效能。

Java 互通

Kotlin 集合底層即為 Java 集合,可無縫傳遞給 Java 方法。