マップ — mapOf() / mutableMapOf()
| 対応: | Kotlin 1.0(2016) |
|---|
Kotlinの『mapOf()』でキーと値のペアを持つ不変マップを、『mutableMapOf()』で可変マップを作成します。『to』中置関数でペアを作り、『[]』演算子や『get()』で値を取得します。
構文
// 不変マップの作成
val capitals = mapOf("日本" to "東京", "フランス" to "パリ")
// 可変マップの作成
val scores = mutableMapOf("item_a" to 85, "item_b" to 72)
scores["item_c"] = 91 // 追加・更新
scores.remove("item_b") // 削除
// 値の取得
val tokyo = capitals["日本"] // "東京"(なければ null)
val default = capitals.getOrDefault("ドイツ", "不明") // "不明"
val safe = capitals.getOrElse("ドイツ") { "不明" } // "不明"
メソッド一覧
| メソッド/プロパティ | 概要 |
|---|---|
| mapOf(k to v, ...) | 不変マップを作成します。 |
| mutableMapOf(k to v, ...) | 可変マップを作成します。 |
| マップ[key] | 値を取得します(なければ null)。 |
| マップ.get(key) | [] と同等です。 |
| マップ.getOrDefault(key, デフォルト) | キーがなければデフォルト値を返します。 |
| マップ.getOrElse(key) { ラムダ } | キーがなければラムダの結果を返します。 |
| マップ.containsKey(key) | キーが存在するか確認します(key in マップ でも可)。 |
| マップ.keys / .values / .entries | キー・値・エントリのコレクションを返します。 |
| MutableMap[key] = value | 値を追加・更新します。 |
| MutableMap.remove(key) | キーと値を削除します。 |
| MutableMap.putIfAbsent(key, value) | キーが存在しない場合のみ追加します。 |
| マップ.map { (k, v) -> } | エントリを変換した新しいリストを返します。 |
| マップ.filter { (k, v) -> } | 条件を満たすエントリのみのマップを返します。 |
サンプルコード
sample_map_create.kt
fun main() {
// 基本の mapOf
val capitals = mapOf(
"日本" to "東京",
"フランス" to "パリ",
"イギリス" to "ロンドン",
"ドイツ" to "ベルリン"
)
// キーアクセス
println(capitals["日本"]) // 東京
println(capitals["スペイン"]) // null
println(capitals.getOrDefault("スペイン", "不明")) // 不明
// 存在確認
println("日本" in capitals) // true
println(capitals.containsKey("中国")) // false
println()
// keys / values / entries
println("国: ${capitals.keys}")
println("首都: ${capitals.values}")
capitals.entries.forEach { (country, capital) ->
println(" $country → $capital")
}
println()
// 可変マップ
val inventory = mutableMapOf("りんご" to 10, "バナナ" to 5)
inventory["オレンジ"] = 8 // 追加
inventory["りんご"] = 15 // 更新
inventory.remove("バナナ") // 削除
println("在庫: $inventory")
// putIfAbsent — 存在しない場合のみ追加します
inventory.putIfAbsent("りんご", 999) // すでにあるのでスキップ
inventory.putIfAbsent("ぶどう", 3) // 追加されます
println("追加後: $inventory")
println()
// キーと値のマップ
val tags = mapOf(
"item_a" to "category_x",
"item_b" to "category_y",
"item_c" to "category_z"
)
println("item_a のタグ: ${tags["item_a"]}")
println()
// map / filter でマップを変換します
val prices = mapOf("りんご" to 150, "バナナ" to 100, "オレンジ" to 200, "ぶどう" to 500)
// 100円超の商品のみ絞り込みます
val expensive = prices.filter { (_, price) -> price > 150 }
println("150円超: $expensive")
// 価格を1.1倍にした新しいマップを作ります
val raised = prices.mapValues { (_, price) -> (price * 1.1).toInt() }
println("10%値上げ後: $raised")
}
map_create.kt
kotlinc map_create.kt -include-runtime -d map_create.jar
java -jar map_create.jar
東京
null
不明
true
false
国: [日本, フランス, イギリス, ドイツ]
首都: [東京, パリ, ロンドン, ベルリン]
日本 → 東京
フランス → パリ
イギリス → ロンドン
ドイツ → ベルリン
在庫: {りんご=15, オレンジ=8}
追加後: {りんご=15, オレンジ=8, ぶどう=3}
item_a のタグ: category_x
150円超: {オレンジ=200, ぶどう=500}
10%値上げ後: {りんご=165, バナナ=110, オレンジ=220, ぶどう=550}
よくあるミス
不変マップへの追加操作、nullキーへのアクセス、『Pair』と『to』中置関数の使い分けに関してよくあるミスをまとめます。
| ミス | 原因と対処 |
|---|---|
| 『mapOf』で作った不変マップに要素を追加しようとする | 『mapOf』は読み取り専用。要素の追加・変更が必要な場合は『mutableMapOf』を使う。 |
| 『map[key]』の結果がnullになることを考慮しない | 存在しないキーへのアクセスは『null』を返す。そのまま使うと『NullPointerException』が発生する。『getOrDefault』やエルビス演算子『?:』で安全に取得する。 |
| 『map[key] != null』で値が null のエントリを見逃す | 値に『null』が入っているエントリはキーが存在していても『map[key] != null』が false になる。キーの存在確認には『containsKey』を使う。 |
| 『Pair("item_a", 85)』を使う | コンパイルエラーではないが、『"item_a" to 85』のように中置関数『to』を使う方が可読性が高い。 |
下記のサンプルコードで、正しい使い方を確認できます。
sample_map_create_mistakes.kt
fun main() {
val scores = mapOf("item_a" to 85, "item_b" to 72)
// 変更が必要なら mutableMapOf を使う
val mutableScores = mutableMapOf("item_a" to 85, "item_b" to 72)
mutableScores["item_c"] = 91
println("追加後: $mutableScores")
// getOrDefault か エルビス演算子 ?: で安全に取得する
val value = scores["item_d"] // null
val safeValue = scores.getOrDefault("item_d", "不明")
println("item_d の値: $safeValue")
// containsKey を使うとキーの存在を正確に確認できる
val nullable = mapOf("item_a" to null)
println(nullable["item_a"] != null) // false(値がnullなので)
println(nullable.containsKey("item_a")) // true(キーは存在する)
// to 中置関数が慣用的な書き方
val m1 = mapOf(Pair("item_a", 85)) // 動くが冗長
val m2 = mapOf("item_a" to 85)
println("m1 == m2: ${m1 == m2}") // true
}
コンパイルして実行すると次のようになります。
kotlinc sample_map_create_mistakes.kt -include-runtime -d sample_map_create_mistakes.jar
java -jar sample_map_create_mistakes.jar
追加後: {item_a=85, item_b=72, item_c=91}
item_d の値: 不明
false
true
m1 == m2: true
概要
Kotlinのマップ操作はリストと同様に関数型スタイルが使えます。『mapValues()』でマップの値だけ変換したり、『filter()』でキー・値の条件で絞り込んだりできます。
マップにはJavaの『LinkedHashMap』が使われるため、挿入順が保証されます(『sortedMapOf()』を使えばキーのアルファベット順になります)。
セットの操作はセット — setOf() / mutableSetOf()を、リストの基本はリスト — 生成 / listOf() / mutableListOf()を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。