Skip to content

Map 專屬操作

Map 中,鍵(Key)與值(Value)的型別皆由使用者定義。以鍵為基礎的 Map 項目存取功能提供了多種 Map 專屬的處理能力,從透過鍵取得值,到對鍵與值進行分別過濾。在本頁中,我們將介紹標準程式庫中提供的 Map 處理函式。

檢索鍵與值

若要從 Map 中檢索值,您必須提供其鍵作為 get() 函式的引數。此外也支援 [key] 這種簡寫語法。如果找不到指定的鍵,則會傳回 null。還有另一個函式 getValue(),其行為略有不同:如果 Map 中找不到該鍵,它會拋出例外。此外,您還有另外兩個處理鍵不存在的選項:

  • getOrElse() 的運作方式與 list 相同:不存在的鍵之值會從指定的 Lambda 函式傳回。
  • getOrDefault() 在找不到鍵時傳回指定的預設值。
kotlin

fun main() {
    val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
    println(numbersMap.get("one"))
    println(numbersMap["one"])
    println(numbersMap.getOrDefault("four", 10))
    println(numbersMap["five"])               // null
    //numbersMap.getValue("six")      // exception!
}

若要對 Map 的所有鍵或所有值執行操作,您可以分別從屬性 keysvalues 中檢索它們。keys 是 Map 所有鍵的集合(Set),而 values 是 Map 所有值的集合。

kotlin

fun main() {
    val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
    println(numbersMap.keys)
    println(numbersMap.values)
}

過濾

您可以使用 filter() 函式以及其他集合來過濾 Map。對 Map 呼叫 filter() 時,請傳遞一個以 Pair 為引數的述詞(Predicate)。這讓您可以在過濾述詞中同時使用鍵與值。

kotlin

fun main() {
    val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
    val filteredMap = numbersMap.filter { (key, value) -> key.endsWith("1") && value > 10}
    println(filteredMap)
}

還有兩種專門用於過濾 Map 的方式:依鍵過濾與依值過濾。每一種方式都有對應的函式:filterKeys()filterValues()。兩者皆會傳回一個包含符合指定述詞之項目的新 Map。filterKeys() 的述詞僅檢查元素的鍵,而 filterValues() 則僅檢查值。

kotlin

fun main() {
    val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
    val filteredKeysMap = numbersMap.filterKeys { it.endsWith("1") }
    val filteredValuesMap = numbersMap.filterValues { it < 10 }

    println(filteredKeysMap)
    println(filteredValuesMap)
}

plus 與 minus 運算子

由於是透過鍵來存取元素,plus (+) 與 minus (-) 運算子在 Map 中的運作方式與其他集合不同。plus 會傳回一個 Map,其中包含其兩個運算元的元素:左側為 Map,右側為 Pair 或另一個 Map。當右側運算元包含左側 Map 中已存在的鍵時,結果 Map 會包含來自右側的項目。

kotlin

fun main() {
    val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
    println(numbersMap + Pair("four", 4))
    println(numbersMap + Pair("one", 10))
    println(numbersMap + mapOf("five" to 5, "one" to 11))
}

minus 會根據左側 Map 的項目建立一個 Map,但排除那些鍵存在於右側運算元中的項目。因此,右側運算元可以是一個單一鍵,或者是鍵的集合:list、set 等。

kotlin

fun main() {
    val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
    println(numbersMap - "one")
    println(numbersMap - listOf("two", "four"))
}

關於在可變 Map 上使用 plusAssign (+=) 與 minusAssign (-=) 運算子的詳細資訊,請參閱下方的 Map 寫入操作

Map 寫入操作

可變 Map 提供專屬的寫入操作。這些操作讓您可以使用以鍵為基礎的存取方式來更改 Map 內容。

定義 Map 寫入操作時有一些特定規則:

  • 值可以更新。相對地,鍵永遠不會改變:一旦您新增了一個項目,其鍵就是固定的。
  • 每個鍵始終只會關聯到一個值。您可以新增或移除整個項目。

以下是可變 Map 上可用的寫入操作標準程式庫函式之說明。

新增與更新項目

若要將新的鍵值對新增至可變 Map,請使用 put()。當一個新項目被放入 LinkedHashMap(預設的 Map 實作)時,它會被新增到迭代 Map 時的最後位置。在排序後的 Map 中,新元素的位置是由其鍵的順序定義的。

kotlin

fun main() {
    val numbersMap = mutableMapOf("one" to 1, "two" to 2)
    numbersMap.put("three", 3)
    println(numbersMap)
}

若要一次新增多個項目,請使用 putAll()。其引數可以是一個 Map 或一組 PairIterableSequenceArray

kotlin

fun main() {
    val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3)
    numbersMap.putAll(setOf("four" to 4, "five" to 5))
    println(numbersMap)
}

如果 Map 中已存在指定的鍵,put()putAll() 都會覆寫其值。因此,您可以使用它們來更新 Map 項目的值。

kotlin

fun main() {
    val numbersMap = mutableMapOf("one" to 1, "two" to 2)
    val previousValue = numbersMap.put("one", 11)
    println("value associated with 'one', before: $previousValue, after: ${numbersMap["one"]}")
    println(numbersMap)
}

您也可以使用運算子簡寫形式將新項目新增至 Map。有兩種方式:

  • plusAssign (+=) 運算子。
  • set() 的運算子別名 []
kotlin

fun main() {
    val numbersMap = mutableMapOf("one" to 1, "two" to 2)
    numbersMap["three"] = 3     // calls numbersMap.put("three", 3)
    numbersMap += mapOf("four" to 4, "five" to 5)
    println(numbersMap)
}

當呼叫時指定的鍵已存在於 Map 中,運算子會覆寫對應項目的值。

移除項目

若要從可變 Map 中移除項目,請使用 remove() 函式。呼叫 remove() 時,您可以傳遞一個鍵或整個鍵值對。如果您同時指定鍵與值,則僅當該鍵的值與第二個引數相符時,該元素才會被移除。

kotlin

fun main() {
    val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3)
    numbersMap.remove("one")
    println(numbersMap)
    numbersMap.remove("three", 4)            //doesn't remove anything
    println(numbersMap)
}

您也可以根據鍵或值從可變 Map 中移除項目。若要執行此操作,請在 Map 的鍵或值上呼叫 remove(),並提供項目的鍵或值。在值上呼叫時,remove() 僅會移除具有指定值的第一個項目。

kotlin

fun main() {
    val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3, "threeAgain" to 3)
    numbersMap.keys.remove("one")
    println(numbersMap)
    numbersMap.values.remove(3)
    println(numbersMap)
}

minusAssign (-=) 運算子也可用於可變 Map。

kotlin

fun main() {
    val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3)
    numbersMap -= "two"
    println(numbersMap)
    numbersMap -= "five"             //doesn't remove anything
    println(numbersMap)
}