String template dengan $ sangat cocok untuk interpolasi sederhana, tetapi saat kita perlu kontrol presisi — lebar kolom tetap, jumlah desimal, padding dengan nol, atau alignment kiri/kanan — kita perlu format gaya C. Kotlin mewarisi mekanisme ini dari Java melalui String.format() dan extension function .format() pada String. Keduanya memanfaatkan java.util.Formatter di balik layar, sehingga seluruh specifier standar tersedia. Chapter ini membongkar specifier yang paling umum, lalu menunjukkan cara membangun tabel terformat yang rapi.
String.format() vs .format() #
Terdapat dua cara memanggil string formatting di Kotlin:
val nama = "Budi"
val umur = 25
// Cara 1: companion function pada String
val s1 = String.format("Nama: %s, Umur: %d", nama, umur)
// Cara 2: extension function pada String
val s2 = "Nama: %s, Umur: %d".format(nama, umur)
println(s1)
println(s2)Kedua cara menghasilkan output identik. Extension function .format() lebih idiomatis di Kotlin karena lebih ringkas dan memungkinkan chaining. Keduanya menerima argumen vararg Any?, sehingga jumlah argumen dapat fleksibel selama cocok dengan jumlah placeholder di format string.
Format Specifier Umum #
Setiap specifier dimulai dengan % dan diikuti konversi. Tabel berikut merangkum specifier yang paling sering dipakai:
| Specifier | Tipe argumen | Output contoh |
|---|---|---|
%s | String, Any | "Budi" |
%d | Int, Long, Short, Byte | 25 |
%f | Float, Double | 175.500000 (default 6 desimal) |
%e | Float, Double | 1.755000e+02 (notasi ilmiah) |
%x | bilangan bulat | ff (255 dalam heksadesimal lowercase) |
%X | bilangan bulat | FF (huruf besar) |
%o | bilangan bulat | 377 (oktal) |
%b | Boolean | true / false |
%c | Char, Int (kode Unicode) | A |
%n | (tanpa argumen) | newline sesuai platform |
%% | (tanpa argumen) | tanda persen literal % |
Contoh String Formatting #
fun main() {
val nama = "Budi"
val umur = 25
val tinggi = 175.5
val aktif = true
println(String.format("Nama: %s", nama))
println("Umur: %d tahun".format(umur))
println("Tinggi: %.2f cm".format(tinggi))
println("Aktif: %b".format(aktif))
val hex = 255
println("Hex: %x".format(hex))
println("HEX: %X".format(hex))
println("Octal via o: %o".format(8))
println("Char: %c".format('A'))
println("%-10s|%10s".format("kiri", "kanan"))
println("%5d dan %05d".format(42, 42))
println("Persen: %.1f%%".format(99.5))
val baris = "| %-15s | %3d | %8.2f |%n"
System.out.printf(baris, "Apel", 10, 15.5)
System.out.printf(baris, "Jeruk", 3, 4.25)
System.out.printf(baris, "Mangga", 100, 250.0)
println("---")
val format = "Halo %s, Anda berumur %d tahun"
println(format.format("Siti", 30))
}Output yang Dihasilkan:
Nama: Budi
Umur: 25 tahun
Tinggi: 175.50 cm
Aktif: true
Hex: ff
HEX: FF
Octal via o: 10
Char: A
kiri | kanan
42 dan 00042
Persen: 99.5%
| Apel | 10 | 15.50 |
| Jeruk | 3 | 4.25 |
| Mangga | 100 | 250.00 |
---
Halo Siti, Anda berumur 30 tahunMari kita telaah baris-baris kode di atas:
- Baris 6 (
String.format("Nama: %s", nama)): pemanggilan companion function. Placeholder%sdiganti dengantoString()dari argumennamabertipeString. Untuk tipe non-primitif,%sselalu memanggiltoString(). - Baris 7 (
"Umur: %d tahun".format(umur)): extension function padaString. Placeholder%dmengharapkan argumen bilangan bulat (Int,Long,Short,Byte). ArgumenumurbertipeInt, cocok. - Baris 8 (
"%.2f"): specifier%fdengan flag.2membatasi jumlah desimal menjadi 2. Tanpa flag,%fdefault menampilkan 6 angka di belakang koma. - Baris 9 (
"%b"): specifier untukBoolean. Output berupatrueataufalselowercase, berbeda denganBoolean.toString()di Kotlin yang juga lowercase, namun%Bakan menghasilkan huruf besarTRUE. - Baris 11–13 (
%x,%X,%o): bilangan bulat255ditampilkan dalam heksadesimal (ff/FF) dan oktal (377). Specifier%Xmemaksa huruf besar untuk digit A-F. - Baris 14 (
"%c"): specifier untuk karakter. Diberi argumenChar'A', ditampilkan apa adanya. ArgumenIntjuga valid — akan dikonversi ke karakter Unicode dengan kode tersebut. - Baris 16 (
"%-10s|%10s"): kombinasi alignment dan width.%-10sartinya string di-padding ke lebar 10 karakter, rata kiri (tanda-).%10sdi-padding ke lebar 10, rata kanan (default tanpa-). Karakter padding default adalah spasi. - Baris 17 (
"%5d dan %05d"):%5dmem-padding angka42menjadi 5 karakter dengan spasi (42).%05dmem-padding dengan nol (00042). - Baris 18 (
"%.1f%%"): specifier%%menampilkan tanda persen literal. Output:Persen: 99.5%. Catatan:%diikuti%bukan placeholder argumen. - Baris 20–24 (
System.out.printf): pemanggilanprintfpadaSystem.out(Java interop).printftidak mengembalikanStringmelainkanPrintStreamdan langsung menulis ke stdout. Placeholder%-15s,%3d,%8.2f, dan%nmenghasilkan kolom yang rapi. - Baris 26–28: variabel
formatbertipeStringmenyimpan format string. Kita dapat memanggil.format(...)kapan pun dibutuhkan, bahkan beberapa kali dengan argumen berbeda.
Width, Precision, dan Flag #
Sintaks lengkap specifier adalah:
%[flag][width][.precision]conversion| Komponen | Fungsi |
|---|---|
Flag - | Rata kiri (default rata kanan) |
Flag 0 | Padding dengan nol (hanya untuk angka) |
Flag + | Tampilkan tanda + untuk angka positif |
Flag , | Tambahkan pemisah grup (locale-dependent) |
Flag ( | Bungkus angka negatif dalam tanda kurung |
| Width | Lebar minimum total field |
| Precision | Untuk %f: jumlah desimal. Untuk %s: panjang maksimum string |
Contoh kombinasi:
%8.2f → " 175.50" (lebar 8, 2 desimal, rata kanan)
%-8.2f → "175.50 " (lebar 8, 2 desimal, rata kiri)
%+8.2f → " +175.50" (tampilkan tanda +)
%08.2f → "00175.50" (padding dengan nol)
%,.2f → "1,234,567.89" (pemisah grup, locale default)printf untuk Tabel Terformat #
Pola paling umum untuk tabel terformat adalah menyimpan format baris di satu variabel, lalu memanggilnya berulang:
fun main() {
val baris = "| %-15s | %3d | %8.2f |%n"
System.out.printf(baris, "Apel", 10, 15.5)
System.out.printf(baris, "Jeruk", 3, 4.25)
System.out.printf(baris, "Mangga", 100, 250.0)
}Karena lebar kolom tetap, tabel tetap rapi meskipun konten memiliki panjang yang berbeda. Pola ini banyak dipakai di program CLI yang melaporkan metrik atau data tabular.
Referensi Lanjutan #
- Kotlin stdlib kotlin.text.format
— halaman
kotlin.text.formatuntuk top-level functionformat() - Java SE 21 Formatter
— dokumentasi
java.util.FormatterJava SE 21 untuk daftar specifier lengkap
Dengan penguasaan specifier dasar, kita siap beranjak ke topik yang lebih spesifik: numeric formatting — penggunaan flag grup, padding nol, dan tanda plus untuk angka.