Skip to content

映射特有操作

映射 中,鍵和值的類型都是使用者定義的。 基於鍵對映射條目 (map entries) 的存取,使得各種映射特有的處理能力得以實現,從透過鍵取得值到單獨對鍵和值進行過濾。 在本頁中,我們將介紹標準函式庫 (standard library) 中映射處理函數的說明。

檢索鍵和值

若要從映射中取得值,您必須將其鍵作為 get() 函數的引數。 同時也支援簡寫語法 [key]。如果找不到給定的鍵,它會回傳 null。 還有一個函數 getValue(),其行為略有不同:如果映射中找不到鍵,它會拋出例外 (exception)。 此外,您還有兩種選項來處理鍵不存在的情況:

  • getOrElse() 的工作方式與列表 (lists) 相同:不存在鍵的值會從給定的 Lambda 函數 (lambda function) 中回傳。
  • 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!
}

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

kotlin

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

過濾

您可以使用 filter() 函數對映射進行過濾,就像對其他集合一樣。 當在映射上呼叫 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)
}

還有兩種針對映射的特定過濾方式:按鍵過濾和按值過濾。 每種方式都有一個函數:filterKeys()filterValues()。 兩者都回傳一個符合給定判斷式的新映射條目。 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 (-) 運算子對映射的工作方式與其他集合不同。 plus 回傳一個 Map,其中包含其兩個運算元 (operands) 的元素:左側的 Map 和右側的 Pair 或另一個 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,但會排除右側運算元中包含的鍵。 因此,右側運算元可以是單一鍵,也可以是鍵的集合:列表、集合 (Set) 等。

kotlin

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

有關在可變映射 (mutable maps) 上使用 plusAssign (+=) 和 minusAssign (-=) 運算子的詳細資訊,請參閱下方的 映射寫入操作

映射寫入操作

可變 映射提供映射特有的寫入操作。 這些操作允許您使用基於鍵的值存取來更改映射內容。

定義映射寫入操作的規則如下:

  • 值可以被更新。然而,鍵永遠不會改變:一旦新增條目,其鍵就是恆定 (constant) 的。
  • 對於每個鍵,總會有一個單一值與其關聯。您可以新增和移除整個條目。

以下是標準函式庫中,可用於可變映射的寫入操作函數說明。

新增和更新條目

若要向可變映射新增新的鍵值對 (key-value pair),請使用 put()。 當新的條目被放入 LinkedHashMap(預設的映射實作)時,它會被新增到迭代映射時的最後一個位置。 在已排序映射 (sorted maps) 中,新元素的位置由其鍵的順序定義。

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)
}

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

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)
}

您也可以使用簡寫運算子形式向映射新增條目。有兩種方式:

  • 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)
}

當使用映射中已存在的鍵呼叫時,運算子會覆寫對應條目的值。

移除條目

若要從可變映射中移除條目,請使用 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)
}

您也可以透過鍵或值從可變映射中移除條目。 若要這樣做,請在映射的鍵或值上呼叫 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 (-=) 運算子也適用於可變映射。

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)
}