Teks yang dibaca dari file, formulir, atau payload API sering kali berbentuk daftar yang dipisahkan karakter tertentu — koma untuk CSV, tab untuk TSV, baris baru untuk log. Sebaliknya, kita juga sering perlu menggabungkan kumpulan string menjadi satu teks dengan pemisah tertentu. Kotlin menyediakan method split untuk memisah dan joinToString untuk menggabung, keduanya dengan banyak overload yang fleksibel. Pada chapter ini kita akan membedah kedua method ini secara menyeluruh, termasuk parameter limit, prefix, suffix, dan transform lambda yang membuat penggabungan bisa disesuaikan per elemen. Pemahaman pola split → proses → join menjadi bekal penting untuk pipeline pemrosesan teks.

split dengan Literal dan Regex #

Method split(delimiter) memecah string menjadi List<String>. Versi literal split(",") memisah berdasar karakter atau string tetap, sedangkan versi split(Regex) memisah berdasar pola. Saat delimiter bisa berupa satu atau lebih karakter (misalnya whitespace beruntun), gunakan split(Regex("\\s+")) agar tidak ada elemen kosong di hasil.

kotlin Contoh: split literal vs regex
val csv = "Budi,Siti,Dewi"
val daftar1 = csv.split(",")             // [Budi, Siti, Dewi]

val kalimat = "Belajar  Kotlin   dengan giat"
val daftar2 = kalimat.split(Regex("\\s+"))  // [Belajar, Kotlin, dengan, giat]

Pemisahan dengan literal sangat cepat karena tidak melibatkan kompilasi pola. Pemisahan dengan Regex lebih fleksibel tetapi memiliki overhead kompilasi — simpan instance Regex di variabel jika dipakai berulang.

Parameter limit #

Method split menerima parameter limit yang membatasi jumlah elemen hasil. Jika limit tercapai, elemen terakhir berisi sisa string yang tidak dipecah lagi. Hal ini berguna untuk parsing baris log yang kolom terakhirnya bisa berisi karakter delimiter:

kotlin Contoh: split dengan limit
val log = "INFO,2026-01-15,Login berhasil dari IP 10.0.0.1"
val bagian = log.split(",", limit = 3)
// [INFO, 2026-01-15, Login berhasil dari IP 10.0.0.1]

Tanpa limit, kolom terakhir yang mengandung koma akan ikut terpecah, sehingga informasi pesan log menjadi terpotong. Dengan limit = 3, sisa string (termasuk koma di dalamnya) tetap utuh di elemen ketiga.

joinToString Dasar #

Method joinToString adalah kebalikan dari split: ia menggabungkan koleksi string menjadi satu String. Parameter wajib hanya separator (default ", "), sedangkan parameter opsional mencakup prefix, postfix, limit, truncated, dan transform.

kotlin Contoh: joinToString dasar
val nama = listOf("Budi", "Siti", "Dewi")
println(nama.joinToString(", "))            // Budi, Siti, Dewi
println(nama.joinToString(" | "))           // Budi | Siti | Dewi
println(nama.joinToString(", ", prefix = "[", postfix = "]"))
// [Budi, Siti, Dewi]

Parameter prefix dan postfix memudahkan pembuatan format bingkai seperti [...] atau {...} tanpa konkatenasi manual.

Parameter limit dan truncated #

Ketika koleksi sangat panjang, mungkin kita hanya ingin menampilkan beberapa elemen pertama diikuti indikator pemotongan. Parameter limit menentukan jumlah maksimum elemen yang ditampilkan, dan truncated menentukan teks yang muncul bila koleksi lebih panjang dari limit:

kotlin Contoh: limit dan truncated
val banyak = (1..100).map { "item$it" }
println(banyak.joinToString(", ", limit = 3, truncated = "..."))
// item1, item2, item3, ...

Pola ini berguna untuk pencatatan log yang tidak boleh membombardir konsol dengan ribuan elemen.

transform Lambda #

Parameter transform adalah lambda (T) -> CharSequence yang mengubah setiap elemen sebelum digabungkan. Lambda ini menghilangkan kebutuhan map terpisah, sehingga kode lebih ringkas dan efisien karena tidak membuat list perantara:

kotlin Contoh: transform lambda
val nama = listOf("Budi", "Siti", "Dewi")
val besar = nama.joinToString(", ") { it.uppercase() }
// BUDI, SITI, DEWI

val angka = listOf(1, 2, 3, 4, 5)
val kuadrat = angka.joinToString(", ") { "${it * it}" }
// 1, 4, 9, 16, 25

Lambda transform juga bisa mengakses indeks melalui overload joinToString dengan transform: (index, element) -> CharSequence bila tersedia di Kotlin versi terbaru, atau dengan mapIndexed terlebih dahulu.

Pola Umum: Split → Proses → Join #

Pola yang sering muncul di pipeline pemrosesan teks adalah split → map → join: memisah input, memproses setiap bagian, lalu menggabungkan kembali. Contoh klasik adalah membersihkan nama dari spasi ganda dan mengubahnya menjadi format tertentu:

kotlin Contoh: pipeline split-proses-join
val masukan = "  Budi  Andi  Siti  "
val rapi = masukan.trim().split(Regex("\\s+")).joinToString(", ")
// Budi, Andi, Siti

Tiga langkah tersebut — trim, split(Regex("\\s+")), joinToString(", ") — secara efektif menormalkan whitespace dan memformat ulang daftar dengan satu baris kode.

Contoh Lengkap dan Outputnya #

File split_join.kt berikut mempraktikkan semua variasi split dan joinToString:

kotlin
fun main() {
    val csv = "Budi,Siti,Dewi,Andi"
    val daftar = csv.split(",")
    println("split comma: $daftar")

    val data = "Budi|Siti|Dewi"
    println("split pipe: ${data.split("|")}")

    val kalimat = "Belajar  Kotlin   dengan  giat"
    val kata = kalimat.split(Regex("\\s+"))
    println("split whitespace regex: $kata")

    val terbatas = csv.split(",", limit = 2)
    println("split limit=2: $terbatas")

    val baris = "satu\ndua\ntiga"
    val isi = baris.split("\n")
    println("split newline: $isi")

    val nama = listOf("Budi", "Siti", "Dewi", "Andi")
    val gabung = nama.joinToString(", ")
    println("joinToString: $gabung")

    val denganPemisah = nama.joinToString(separator = " | ")
    println("separator khusus: $denganPemisah")

    val denganBingkai = nama.joinToString(", ", prefix = "[", postfix = "]")
    println("prefix+suffix: $denganBingkai")

    val transformasi = nama.joinToString(", ") { it.uppercase() }
    println("transform uppercase: $transformasi")

    val angka = listOf(1, 2, 3, 4, 5)
    val kuadrat = angka.joinToString(", ") { "${it * it}" }
    println("kuadrat: $kuadrat")

    val dibatasi = nama.joinToString(", ", limit = 2, truncated = "...dst")
    println("limit+truncated: $dibatasi")

    val pasangan = listOf("Budi" to 28, "Siti" to 30)
    val ringkas = pasangan.joinToString("; ") { "${it.first}=${it.second}" }
    println("format kustom: $ringkas")

    val kosong = emptyList<String>()
    println("empty join: '${kosong.joinToString(", ")}'")

    val teksPanjang = "kotlin java python go rust"
    val dibalik = teksPanjang.split(" ").joinToString("-") { it.reversed() }
    println("kata dibalik: $dibalik")
}

Output yang Dihasilkan:

text
split comma: [Budi, Siti, Dewi, Andi]
split pipe: [Budi, Siti, Dewi]
split whitespace regex: [Belajar, Kotlin, dengan, giat]
split limit=2: [Budi, Siti,Dewi,Andi]
split newline: [satu, dua, tiga]
joinToString: Budi, Siti, Dewi, Andi
separator khusus: Budi | Siti | Dewi | Andi
prefix+suffix: [Budi, Siti, Dewi, Andi]
transform uppercase: BUDI, SITI, DEWI, ANDI
kuadrat: 1, 4, 9, 16, 25
limit+truncated: Budi, Siti, ...dst
format kustom: Budi=28; Siti=30
empty join: ''
kata dibalik: niltok-avaj-nohtyp-og-tsur

Mari kita telaah bagian penting dari kode di atas. Baris csv.split(",") memisah string menjadi empat elemen tanpa mempertahankan karakter koma. Baris kalimat.split(Regex("\\s+")) menggunakan regex untuk memisah berdasarkan satu atau lebih whitespace, sehingga spasi ganda tidak menghasilkan elemen kosong. Baris csv.split(",", limit = 2) membatasi hasil menjadi dua elemen, dengan elemen kedua berisi sisa string. Baris nama.joinToString(", ") { it.uppercase() } menggunakan transform lambda untuk mengubah setiap elemen menjadi huruf kapital sebelum digabungkan. Baris pasangan.joinToString("; ") { "${it.first}=${it.second}" } menunjukkan transformasi kompleks yang memformat pasangan key-value. Baris terakhir teksPanjang.split(" ").joinToString("-") { it.reversed() } memperlihatkan pipeline lengkap: split, transformasi, join.

Referensi Lanjutan #

  • kotlin.text package — API reference split, joinToString, dan joinTo di paket kotlin.text
  • Strings — konteks pemrosesan string dasar pada panduan resmi

Penutup #

Dengan split dan joinToString, kita memiliki pasangan alat untuk membongkar dan merakit kembali teks terstruktur. Namun, banyak operasi teks sebenarnya bekerja di tingkat karakter, bukan substring — misalnya menghitung jumlah huruf, memeriksa jenis karakter, atau mengubah huruf menjadi kode numerik. Topik pengolahan karakter menjadi fokus chapter Character Processing.