Setelah mempelajari semua jenis collection dan operasinya, pertanyaan yang muncul adalah: untuk masalah tertentu, collection mana yang sebaiknya dipilih? Pilihan yang tepat membuat kode lebih jelas, lebih aman, dan lebih cepat. Pada chapter ini kita akan merangkum panduan praktis dalam bentuk decision tree dan tabel perbandingan, lalu menerapkannya pada delapan skenario konkret yang sering dijumpai di aplikasi nyata.
Decision Tree Memilih Collection #
Berikut panduan praktis memilih collection berdasarkan kebutuhan:
| Kebutuhan | Pilihan | Alasan |
|---|---|---|
| Urutan penting, duplikat wajar | List | Berurutan, menerima duplikat, akses indeks O(1) |
| Elemen harus unik | Set | Menolak duplikat, cek keanggotaan cepat |
| Pasangan key-value, lookup cepat | Map | Akses O(1) berdasarkan key |
| Ukuran tetap, tipe primitif, hot path | IntArray / LongArray / dll. | Tanpa boxing, memori efisien |
Interop Java varargs T[] | Array<T> | Tipe array objek Java |
| Pipeline panjang + koleksi besar | Sequence | Lazy evaluation, short-circuit |
| Perlu add/remove saat runtime | MutableList / MutableSet / MutableMap | Mutasi terkendali |
Pertanyaan Pertama: Apakah Perlu Mutasi? #
Pertanyaan paling penting adalah apakah collection akan dimodifikasi setelah dibuat. Default gunakan read-only (List, Set, Map). Hanya bila mutasi benar-benar diperlukan, gunakan variant mutable.
| Varian Read-Only | Varian Mutable | Operasi Mutasi |
|---|---|---|
List<T> | MutableList<T> | add, removeAt, set |
Set<T> | MutableSet<T> | add, remove |
Map<K, V> | MutableMap<K, V> | put, remove, compute |
Pertanyaan Kedua: Tipe Data Apa? #
- Objek (
String,data class,Int?): gunakanList<T>/MutableList<T>. - Primitif numerik dalam jumlah besar atau hot path: gunakan
IntArray/LongArray/DoubleArray/ dll. - Interoperabilitas Java: gunakan
Array<T>untukT[]Java atau array primitif untukint[].
Pertanyaan Ketiga: Pola Akses? #
- Akses berbasis indeks (
coll[i]):List(acakO(1)). - Akses berbasis key:
Map(O(1)rata-rata). - Cek keanggotaan:
Set(O(1)rata-rata, lebih cepat dariList.contains). - Iterasi sekali, lazy:
Sequence(hemat alokasi pada pipeline panjang).
Contoh Lengkap #
data class Produk(val nama: String, val kategori: String, val harga: Int, val stok: Int)
fun main() {
// === Skenario 1: Daftar urutan transaksi ===
// List cocok karena: urutan penting, duplikat wajar, akses indeks
val antrianPesanan = listOf("P001", "P002", "P003", "P002", "P004")
println("Antrian pesanan: $antrianPesanan")
println("Pesanan pertama: ${antrianPesanan.first()}")
println("Jumlah total: ${antrianPesanan.size}")
// === Skenario 2: Daftar ID unik pengguna ===
// Set cocok karena: tidak boleh ada duplikat
val idPengguna = setOf("U001", "U002", "U003", "U001")
println("ID pengguna unik: ${idPengguna.sorted()}")
println("Jumlah pengguna unik: ${idPengguna.size}")
// === Skenario 3: Pemetaan kode produk ke stok ===
// Map cocok karena: lookup berdasarkan key, key unik
val stokProduk = mapOf(
"K001" to 50,
"K002" to 30,
"K003" to 75
)
println("Stok K002: ${stokProduk["K002"]}")
println("Semua kode: ${stokProduk.keys.sorted()}")
// === Skenario 4: Data kuantitatif besar (suhu sensor) ===
// Array primitif cocok karena: ukuran tetap, tipe primitif, hot path
val suhuSensor = doubleArrayOf(36.5, 36.7, 36.6, 36.8, 36.5, 36.7)
println("Suhu rata-rata: ${suhuSensor.average()}")
println("Suhu maks: ${suhuSensor.maxOrNull()}")
// === Skenario 5: Build collection sementara ===
// MutableList cocok karena: perlu add/remove saat build
val tagDipilih = mutableListOf<String>()
tagDipilih.add("kotlin")
tagDipilih.add("jvm")
tagDipilih.add("backend")
println("Tag: $tagDipilih")
// === Skenario 6: Cache nilai yang dihitung ===
// MutableMap cocok karena: tambah/update value seiring waktu
val cache = mutableMapOf<String, Int>()
val panjang = cache.getOrPut("kotlin") { "kotlin".length }
println("Cache panjang \"kotlin\": $panjang")
println("Isi cache: $cache")
// === Skenario 7: Interop dengan API Java varargs ===
// Array cocok karena: Java varargs memerlukan T[]
fun jumlahkan(vararg x: Int): Int = x.sum()
val argumen = arrayOf(1, 2, 3, 4, 5)
val total = jumlahkan(*argumen.toIntArray())
println("Total dari array Java: $total")
// === Skenario 8: Pipeline panjang dengan take awal ===
// Sequence cocok karena: lazy, short-circuit, koleksi besar
val data = (1..1_000_000).toList()
val limaKuadrat = data
.asSequence()
.map { it * it }
.filter { it > 10 }
.take(5)
.toList()
println("Lazy pipeline: $limaKuadrat")
// === Decision Tree Ringkas ===
println("--- Decision Tree ---")
println("Butuh akses indeks O(1)? -> List")
println("Butuh duplikat? -> List")
println("Butuh keunikan elemen? -> Set")
println("Pasangan key-value? -> Map")
println("Ukuran tetap, tipe primitif, hot path? -> IntArray/LongArray/...")
println("Interop Java varargs? -> Array<T>")
println("Pipeline panjang + koleksi besar? -> Sequence")
println("Koleksi perlu diubah? -> Mutable variant")
}Output yang Dihasilkan:
Antrian pesanan: [P001, P002, P003, P002, P004]
Pesanan pertama: P001
Jumlah total: 5
ID pengguna unik: [U001, U002, U003]
Jumlah pengguna unik: 3
Stok K002: 30
Semua kode: [K001, K002, K003]
Suhu rata-rata: 36.63333333333333
Suhu maks: 36.8
Tag: [kotlin, jvm, backend]
Cache panjang "kotlin": 6
Isi cache: {kotlin=6}
Total dari array Java: 15
Lazy pipeline: [16, 25, 36, 49, 64]
--- Decision Tree ---
Butuh akses indeks O(1)? -> List
Butuh duplikat? -> List
Butuh keunikan elemen? -> Set
Pasangan key-value? -> Map
Ukuran tetap, tipe primitif, hot path? -> IntArray/LongArray/...
Interop Java varargs? -> Array<T>
Pipeline panjang + koleksi besar? -> Sequence
Koleksi perlu diubah? -> Mutable variantMari kita bedah pemilihan collection pada skenario-skenario di atas:
- Skenario 1 (antrian pesanan):
Listdipilih karena pesanan boleh berulang (ID"P002"muncul dua kali) dan urutan transaksi penting.Setakan membuang duplikat — bukan yang kita inginkan di sini. - Skenario 2 (ID pengguna unik):
Setdipilih karena ID tidak boleh ada duplikat. PemanggilansetOf("U001", ..., "U001")hanya menyimpan satu"U001". - Skenario 3 (stok per kode):
Mapdipilih karena kita mencari stok berdasarkan kode produk. AksesstokProduk["K002"]adalahO(1), jauh lebih cepat daripada mencari di list of pairs. - Skenario 4 (suhu sensor):
DoubleArraydipilih karena data numerik kontinu, ukuran tetap (jumlah sensor), dan sering dipakai dalam perhitungan (average, max). Boxing padaList<Double>akan boros memori. - Skenario 5 (tag dipilih):
MutableListdipilih karena kita membangun list secara bertahap dari input pengguna. Bila tag harus unik, gunakanMutableSetsebagai gantinya. - Skenario 6 (cache):
MutableMapdipilih karena kita menambah dan memperbarui key-value seiring waktu.getOrPutadalah idiom kanonik untuk cache — lambda hanya dievaluasi saat key belum ada. - Skenario 7 (varargs Java):
Array<Int>dipilih karena API Javavarargmemerlukanint[]. Karena signature fungsi adalahvararg Int, kita perlu mengonversiArray<Int>keIntArraylebih dulu dengantoIntArray(). - Skenario 8 (pipeline panjang):
Sequencedipilih karena koleksi berukuran satu juta dan kita hanya butuh 5 elemen hasil. Lazy evaluation berhenti setelah 5 elemen terkumpul, menghindari alokasi list antara yang besar.
Tabel Ringkas Komparatif #
| Aspek | List | Set | Map | Array | Primitive Array | Sequence |
|---|---|---|---|---|---|---|
| Duplikat | Ya | Tidak | Key unik | Ya | Ya | Ya |
| Urutan | Berurutan | Tidak (default) | Penyisipan | Berurutan | Berurutan | Sesuai sumber |
Akses indeks O(1) | Ya | Tidak | Key O(1) | Ya | Ya | Tidak |
| Ukuran tetap | Tidak (mutable) | Tidak (mutable) | Tidak (mutable) | Ya | Ya | Lazy |
| Mutasi elemen | Mutable var | Mutable var | Mutable var | Ya | Ya | Tidak |
| Boxing | Ya/Bebas | Ya/Bebas | Ya/Bebas | Ya | Tidak | Ya/Bebas |
| Cocok untuk | Daftar urutan | Keunikan | Lookup key | Interop | Hot path numerik | Pipeline panjang |
Referensi Lanjutan #
- Collections overview
— tinjauan umum untuk memilih
List,Set,Map - Set
— kapan memakai
Setuntuk keunikan elemen - Map
— kapan memakai
Mapuntuk lookup key
Dengan panduan ini, kita siap memilih collection yang tepat untuk berbagai skenario yang akan ditemui dalam pengembangan aplikasi Kotlin. Section Collections selesai, dan kita akan melanjutkan ke topik lanjutan berikutnya pada section selanjutnya.