String.format pada chapter sebelumnya membangun string terformat; pada banyak kasus langkah berikutnya langsung mencetaknya. Java menyatukan dua langkah tersebut dalam satu method: System.out.printf. Mesin yang dipakai tetap java.util.Formatter, sehingga seluruh specifier yang sudah kita kenal — %s, %d, %f, %n — bekerja dengan aturan yang sama. Yang baru pada chapter ini adalah sisi tata letak: lebar kolom, perataan, flag angka, dan pemisah ribuan yang sadar Locale.

printf sebagai Pintu Cepat #

Method printf(String template, Object... args) memformat template lalu langsung menulis hasilnya ke System.out tanpa perantara variabel. Sebagai method milik PrintStream, printf mengembalikan PrintStream itu sendiri, sehingga panggilan dapat dirantai — System.out.printf(...).printf(...) — meskipun bentuk tersebut jarang memberi keuntungan baca. Satu hal yang sering terlupakan: printf tidak menambahkan baris baru secara otomatis, jadi %n harus ditulis eksplisit di akhir template.

Lebar Kolom dan Perataan #

Angka lebar (width) yang ditulis di antara % dan conversion menyatakan jumlah karakter minimum yang dialokasikan untuk satu nilai. Angka rata kanan secara bawaan; teks juga rata kanan, tetapi flag - membaliknya menjadi rata kiri. Kombinasi keduanya memadatkan tabel yang sebelumnya mustahil dirapikan dengan tab:

java TabelRapi.java
public class TabelRapi {
    public static void main(String[] args) {
        System.out.printf("%-12s|%6s|%10s%n", "Item", "Qty", "Harga");
        System.out.printf("%-12s|%6d|%10.2f%n", "Buku Tulis", 2, 15000.0);
        System.out.printf("%-12s|%6d|%10.2f%n", "Pena Hitam", 5, 3000.0);
        System.out.printf("%-12s|%6d|%10.2f%n", "Penggaris", 1, 7500.0);
        System.out.printf("%-12s|%6d|%10.2f%n", "TOTAL", 8, 25500.0);
    }
}

Output yang Dihasilkan:

text
Item        |   Qty|     Harga
Buku Tulis  |     2|  15000.00
Pena Hitam  |     5|   3000.00
Penggaris   |     1|   7500.00
TOTAL       |     8|  25500.00

Mari kita baca specifier-spesifiernya:

  1. %-12s (kolom Item): nama item ditata rata kiri dalam lebar 12 karakter; teks yang lebih pendek diberi spasi penambah di kanan, teks yang lebih panjang dicetak utuh tanpa terpotong.
  2. %6d (kolom Qty): angka rata kanan dalam lebar 6 — spasi penambah berada di kiri, sehingga digit satuan tiap baris sejajar vertikal.
  3. %10.2f (kolom Harga): gabungan lebar 10 dan presisi .2; nilainya dibulatkan tampilan menjadi dua desimal lalu ditata rata kanan, membuat 15000.00, 3000.00, dan 25500.00 sejajar pada koma desimalnya.

Karakter | di antara specifier hanyalah teks biasa di dalam template — pembatas kolom yang ikut tercetak apa adanya.

Flag untuk Angka dan Teks #

Flag adalah satu karakter yang diletakkan tepat setelah % untuk mengubah perilaku cetak. Flag yang paling sering dipakai:

FlagNamaEfek
-left-justifiedrata kiri dalam lebar kolom
+plus signtanda selalu dicetak, juga untuk nilai positif
0zero paddingkolom kosong diisi angka nol
,groupingpemisah ribuan sesuai Locale
(parenthesesnilai negatif dibungkus tanda kurung
spacenilai positif diawali satu spasi

Program berikut menguji flag-flag tersebut satu per satu:

java FormatFlag.java
public class FormatFlag {
    public static void main(String[] args) {
        System.out.printf("Tanda plus   : %+d dan %+d%n", 42, -42);
        System.out.printf("Nol di depan : %05d%n", 42);
        System.out.printf("Tanda kurung : %(d dan %(d%n", 42, -42);
        System.out.printf("Spasi tanda  : % d dan % d%n", 42, -42);
        System.out.printf("Presisi teks : %.5s%n", "PemrogramanJava");
    }
}

Output yang Dihasilkan:

text
Tanda plus   : +42 dan -42
Nol di depan : 00042
Tanda kurung : 42 dan (42)
Spasi tanda  :  42 dan -42
Presisi teks : Pemro

Flag + dan ( sama-sama berurusan dengan tanda: + mencetak tanda positif secara eksplisit (berguna untuk kolom selisih angka), sedangkan ( menampilkan negatif sebagai (42) — gaya akuntansi yang menghindari tanda minus. Flag 0 mengisi ruang kosong dengan nol sehingga %05d menghasilkan 00042, lazim untuk nomor urut. Flag spasi memberi satu spasi bagi nilai positif agar sejajar dengan tanda minus milik nilai negatif. Perlu dicatat bahwa presisi berlaku juga untuk teks: %.5s memotong string menjadi lima karakter pertama — PemrogramanJava menjadi Pemro.

Pemisah Ribuan Bergantung Locale #

Flag , mengaktifkan pemisah ribuan — tetapi karakter pemisahnya bukan ditentukan oleh flag, melainkan oleh Locale yang berlaku. Tanpa parameter tambahan, printf memakai Locale default mesin yang menjalankan program. Method ini juga punya overload printf(Locale, template, args...) yang memaksa locale tertentu tanpa peduli pengaturan mesin:

java FormatAngka.java
import java.util.Locale;

public class FormatAngka {
    public static void main(String[] args) {
        long penduduk = 277523122;
        double pendapatan = 12500000.0;

        System.out.printf("Locale default: %s%n", Locale.getDefault());
        System.out.printf("Penduduk      : %,d%n", penduduk);
        System.out.printf("Pendapatan    : %,.2f%n", pendapatan);
        System.out.printf(Locale.US, "Locale US    : %,d | %,.2f%n", penduduk, pendapatan);
        System.out.printf(Locale.of("id", "ID"), "Locale id-ID : %,d | %,.2f%n", penduduk, pendapatan);
    }
}

Output yang Dihasilkan:

text
Locale default: en_US
Penduduk      : 277,523,122
Pendapatan    : 12,500,000.00
Locale US    : 277,523,122 | 12,500,000.00
Locale id-ID : 277.523.122 | 12.500.000,00

Pada lingkungan eksekusi buku ini, Locale default adalah en_US, sehingga dua baris pertama dan baris Locale US sama-sama menampilkan 277,523,122 dan 12,500,000.00. Baris terakhir memaksa id-ID dan hasilnya berubah menjadi 277.523.122 dengan 12.500.000,00 — titik sebagai pemisah ribuan dan koma sebagai desimal.

Pemisah ribuan hanyalah satu dari banyak pengaruh Locale terhadap tampilan angka. Bagaimana dengan simbol mata uang, persentase, dan pola desimal yang sepenuhnya kustom? Chapter Locale dan Format Angka membedah class NumberFormat dan DecimalFormat untuk kebutuhan tersebut.

Referensi #

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

FormatAngka.java

Unduh berkas
java
import java.util.Locale;

public class FormatAngka {
    public static void main(String[] args) {
        long penduduk = 277523122;
        double pendapatan = 12500000.0;

        System.out.printf("Locale default: %s%n", Locale.getDefault());
        System.out.printf("Penduduk      : %,d%n", penduduk);
        System.out.printf("Pendapatan    : %,.2f%n", pendapatan);
        System.out.printf(Locale.US, "Locale US    : %,d | %,.2f%n", penduduk, pendapatan);
        System.out.printf(Locale.of("id", "ID"), "Locale id-ID : %,d | %,.2f%n", penduduk, pendapatan);
    }
}

FormatFlag.java

Unduh berkas
java
public class FormatFlag {
    public static void main(String[] args) {
        System.out.printf("Tanda plus   : %+d dan %+d%n", 42, -42);
        System.out.printf("Nol di depan : %05d%n", 42);
        System.out.printf("Tanda kurung : %(d dan %(d%n", 42, -42);
        System.out.printf("Spasi tanda  : % d dan % d%n", 42, -42);
        System.out.printf("Presisi teks : %.5s%n", "PemrogramanJava");
    }
}

TabelRapi.java

Unduh berkas
java
public class TabelRapi {
    public static void main(String[] args) {
        System.out.printf("%-12s|%6s|%10s%n", "Item", "Qty", "Harga");
        System.out.printf("%-12s|%6d|%10.2f%n", "Buku Tulis", 2, 15000.0);
        System.out.printf("%-12s|%6d|%10.2f%n", "Pena Hitam", 5, 3000.0);
        System.out.printf("%-12s|%6d|%10.2f%n", "Penggaris", 1, 7500.0);
        System.out.printf("%-12s|%6d|%10.2f%n", "TOTAL", 8, 25500.0);
    }
}