Map<K, V> menyimpan pasangan key-value. Berbeda dengan List dan Set yang menyimpan nilai tunggal, Map memetakan sebuah key ke sebuah value — misalnya kode negara ke kota, atau ID pengguna ke profil. Pada chapter ini kita akan membuat map, mengakses nilai berdasarkan key, mengiterasi pasangan, dan memahami sifat urutan penyisipan yang menjadi jaminan default di pustaka standar Kotlin.
Membuat Map Read-Only #
Map dibuat menggunakan mapOf(...) dengan pasangan key to value. Infix function to membuat objek Pair<K, V> yang kemudian dimasukkan ke map.
val kota: Map<String, String> = mapOf(
"Jepang" to "Tokyo",
"Korea" to "Seoul",
"Indonesia" to "Jakarta"
)
val kosong: Map<String, Int> = emptyMap()
val dariList = listOf("a" to 1, "b" to 2).toMap()Map read-only tidak bisa diubah isinya; tidak ada metode put atau remove. Nilai yang disimpan bisa nullable (Map<String, Int?>), dan value dengan key yang sama hanya disimpan sekali — key berikutnya menimpa key sebelumnya pada saat konstruksi.
Mengakses Nilai #
Nilai diakses melalui operator subscript map[key] atau metode get(key). Karena key mungkin tidak ada, hasil aksesnya bertipe nullable (V?) meskipun value sebenarnya non-null.
| Operasi | Mengembalikan | Catatan |
|---|---|---|
map[key] | V? | null jika key tidak ada |
map.get(key) | V? | Sama dengan subscript |
map.getOrDefault(key, default) | V | Mengembalikan default jika key tidak ada |
map.getOrElse(key) { ... } | V | Lambda dievaluasi saat key tidak ada |
map.getValue(key) | V | Melempar NoSuchElementException jika tidak ada |
keys, values, entries #
Tiga properti ini memberi kita view ke isi map:
map.keys—Set<K>berisi semua key.map.values—Collection<V>berisi semua value (boleh duplikat).map.entries—Set<Map.Entry<K, V>>berisi pasangan key-value.
Ketiganya adalah view — perubahan pada map (versi mutable) akan tercermin pada ketiga collection ini.
Iterasi dan Urutan Penyisipan #
mapOf di JVM menghasilkan LinkedHashMap, sehingga iterasi mempertahankan urutan penyisipan. Dua gaya iterasi yang paling sering dipakai:
for ((key, value) in map) {
println("$key -> $value")
}
map.entries.forEach { (k, v) -> println("$k: $v") }Deklarasi (k, v) adalah destructuring declaration — Kotlin memecah Map.Entry menjadi dua variabel.
Contoh Lengkap #
Berikut program yang merangkum operasi dasar Map:
fun main() {
val kota: Map<String, String> = mapOf(
"Jepang" to "Tokyo",
"Korea" to "Seoul",
"Indonesia" to "Jakarta"
)
// Akses nilai dengan operator []
println("Kota Jepang: ${kota["Jepang"]}")
println("Kota Prancis: ${kota["Prancis"]}")
// Akses aman
println("getOrElse: ${kota.getOrElse("Prancis") { "(tidak ada)" }}")
println("getOrDefault: ${kota.getOrDefault("Prancis", "—")}")
println("getOrNull: ${kota["Prancis"]}")
// keys, values, entries
println("Keys: ${kota.keys}")
println("Values: ${kota.values}")
println("Entries: ${kota.entries}")
// Iterasi: insertion order dipertahankan (LinkedHashMap)
println("Iterasi map:")
for ((negara, namaKota) in kota) {
println(" $negara -> $namaKota")
}
// Iterasi entries
println("Iterasi entries:")
kota.entries.forEach { (k, v) -> println(" $k: $v") }
// containsKey, containsValue
println("Ada key \"Jepang\"? ${kota.containsKey("Jepang")}")
println("Ada value \"Seoul\"? ${kota.containsValue("Seoul")}")
// Map dengan nilai nullable
val catatan: Map<String, Int?> = mapOf("a" to 1, "b" to null, "c" to 3)
println("Nilai b: ${catatan["b"]}")
println("Nilai d: ${catatan["d"]}") // key tidak ada -> null
// Mengonversi list pasangan menjadi map
val pasangan = listOf("x" to 10, "y" to 20, "z" to 30)
val dariList: Map<String, Int> = pasangan.toMap()
println("Map dari list: $dariList")
// empty map
val kosong: Map<String, String> = emptyMap()
println("Map kosong size: ${kosong.size}")
}Output yang Dihasilkan:
Kota Jepang: Tokyo
Kota Prancis: null
getOrElse: (tidak ada)
getOrDefault: —
getOrNull: null
Keys: [Jepang, Korea, Indonesia]
Values: [Tokyo, Seoul, Jakarta]
Entries: [Jepang=Tokyo, Korea=Seoul, Indonesia=Jakarta]
Iterasi map:
Jepang -> Tokyo
Korea -> Seoul
Indonesia -> Jakarta
Iterasi entries:
Jepang: Tokyo
Korea: Seoul
Indonesia: Jakarta
Ada key "Jepang"? true
Ada value "Seoul"? true
Nilai b: null
Nilai d: null
Map dari list: {x=10, y=20, z=30}
Map kosong size: 0Mari kita bedah baris-baris penting di atas:
kota["Jepang"]: subscript setara dengankota.get("Jepang"). Mengembalikan"Tokyo"bertipeString?.kota.getOrElse("Prancis") { "(tidak ada)" }: karena"Prancis"tidak ada sebagai key, lambda dijalankan dan mengembalikan string default. Tipe hasilnyaString, bukanString?.for ((negara, namaKota) in kota): destructuring pada setiapMap.Entry, memberi kita dua variabel bernamanegaradannamaKotatanpa harus memanggilentry.keyatauentry.value.catatan["b"]dancatatan["d"]: keduanya mengembalikannull, tetapi dengan sebab berbeda."b"ada dengan valuenull;"d"tidak ada sebagai key. TipeMap<String, Int?>tidak bisa membedakan kedua kasus — perlucontainsKeyuntuk memisahkannya.pasangan.toMap(): mengubahList<Pair<String, Int>>menjadiMap<String, Int>. Berguna ketika kita membangun pasangan secara dinamis sebelum membekukannya menjadi map.
Referensi Lanjutan #
- Map
— panduan resmi
Map<K, V>read-only - Map API reference
— API reference
kotlin.collections.Map
Setelah menguasai Map read-only, kita akan melihat versi mutable yang memungkinkan kita memperbarui nilai dan menambah key baru saat program berjalan.