Text Block dan Metode String Modern

Merapikan teks dengan text block serta memakai isBlank, lines, repeat, dan strip dari Java 11.

Daftar isi

Sintaks text block, aturan indentasi insidental, dan escape khususnya sudah dipraktikkan pada topik Text Block di modul Array dan String. Topik ini melengkapi sisi pemakaiannya dengan metode String yang ditambahkan Java 11 dan paling sering berpasangan dengan text block, yaitu isBlank, lines, repeat, dan strip beserta dua turunannya. Keempatnya memindahkan pekerjaan merapikan teks yang dulu ditulis manual dengan split dan perulangan menjadi beberapa pemanggilan metode yang langsung terbaca. Setelah selesai, teks multi-baris seperti catatan yang disalin dari file atau dari tempelan lain dapat dibersihkan, dipotong per baris, dan disusun ulang menjadi laporan yang rapi.

Membersihkan teks dengan strip dan isBlank#

Metode strip menghapus spasi di awal dan akhir string, sama seperti trim yang lebih tua, tetapi definisi spasinya berbeda. trim hanya menghapus karakter berkode sampai U+0020, sedangkan strip mengikuti Character.isWhitespace sehingga mengenali spasi Unicode yang lebih lebar dari itu. Perbedaannya terasa ketika teks berasal dari dokumen atau tabel yang menyisipkan spasi khusus, misalnya U+2002 yang selebar huruf n.

java DemoMetodeTeks11.java
public class DemoMetodeTeks11 {

    public static void main(String[] args) {
        String berSpasiUnicode = "\u2002ali\u2002";
        System.out.println("panjang trim : " + berSpasiUnicode.trim().length());
        System.out.println("panjang strip: " + berSpasiUnicode.strip().length());

        String kosong = "   ";
        System.out.println("isEmpty : " + kosong.isEmpty());
        System.out.println("isBlank : " + kosong.isBlank());

        String garis = "-".repeat(20);
        System.out.println(garis);
        System.out.println("panjang repeat(0): " + "x".repeat(0).length());

        try {
            "ab".repeat(-1);
        } catch (IllegalArgumentException e) {
            System.out.println("Tertangkap: " + e.getMessage());
        }
    }
}
text Keluaran
panjang trim : 5
panjang strip: 3
isEmpty : false
isBlank : true
--------------------
panjang repeat(0): 0
Tertangkap: count is negative: -1

String awalnya memuat lima karakter, yaitu spasi U+2002, kata ali, dan spasi U+2002 lagi. Hasil trim tetap berpanjang 5 karena kedua spasinya berada di atas U+0020, sedangkan strip menghapus keduanya dan menyisakan tiga karakter. Dua baris berikutnya menunjukkan pasangan lain yang sering tertukar, yaitu isEmpty yang menghitung panjang dan isBlank yang menghitung isi. String " " tidak kosong, tetapi blank karena hanya berisi spasi, sehingga pemeriksaan baris yang “tidak berisi apa pun” sebaiknya memakai isBlank.

Memecah teks per baris dengan lines#

Metode lines memecah string menjadi baris-barisnya dan menghasilkan Stream<String> yang tiap elemennya sudah tanpa penanda baris. Metode ini mengenali tiga bentuk penanda baris sekaligus, yaitu \n, \r\n, dan \r tunggal, sehingga teks dari sistem yang berbeda tidak meninggalkan karakter \r yang menempel di akhir baris. Cara lama dengan split("\n") bekerja pada pola regex, tidak mengenali \r\n secara utuh, dan perilakunya terhadap baris kosong di ujung juga berbeda dari lines.

Karena hasilnya Stream, baris-baris tersebut diubah menjadi List dengan toList terlebih dahulu agar mudah diperulangkan dengan indeks hitungan. Program berikut merapikan catatan daftar hadir yang isinya tidak rapi, lengkap dengan baris kosong dan indentasi yang tak konsisten.

java DemoRapikanDaftar.java
public class DemoRapikanDaftar {

    public static void main(String[] args) {
        String catatan = """
                Ali
                  Budi
                Citra

                   Dewi
                """;

        int nomor = 0;
        for (String baris : catatan.lines().toList()) {
            String nama = baris.strip();
            if (nama.isBlank()) {
                continue;
            }
            nomor++;
            System.out.println(nomor + ". " + nama);
        }
        System.out.println("Total nama: " + nomor);
    }
}
text Keluaran
1. Ali
2. Budi
3. Citra
4. Dewi
Total nama: 4

Program ini memperlihatkan pembagian tugas yang jelas antara text block dan metode String modernnya. Text block menyimpan catatan apa adanya, lines memotongnya menjadi baris, strip membersihkan indentasi yang tersisa di setiap baris, dan isBlank menyaring baris kosong sehingga hitungan nomor tidak tergeser. Pola empat langkah ini berlaku untuk pekerjaan sejenis, misalnya merapikan daftar belanja atau menyaring log sebelum disimpan.

Mengulang teks dengan repeat#

Metode repeat menggabungkan string dengan dirinya sendiri sebanyak hitungan yang diberikan, dan hasilnya tetap bertipe String. Pemanggilan "-".repeat(20) menyusun garis dari dua puluh tanda hubung, sedangkan " ".repeat(4) menghasilkan indentasi empat spasi tanpa mengetiknya manual. Hitungan nol sah dan menghasilkan string kosong, sebagaimana terlihat pada keluaran demo sebelumnya dengan panjang repeat(0): 0.

Bentuk pemakaiannya paling sederhana pada penyusunan pemisah dan penyok teks.

java Contoh: pemisah dan indentasi dengan repeat
// tidak-dijalankan
String pemisah = "-".repeat(24);
String butir = " ".repeat(4) + "kopi hitam";

Hitungan negatif tidak ditoleransi. Pemanggilan "ab".repeat(-1) melempar IllegalArgumentException dengan pesan count is negative: -1, dan demo pada bagian pertama menangkap exception itu secara langsung. Ketika hitungan datang dari variabel yang nilainya belum pasti, misalnya lebar kolom hasil perhitungan, pemeriksaan Math.max(0, lebar) mencegah exception itu sebelum terjadi.

Laporan berbingkai dari templat text block#

Perpaduan ketiga metode di atas dengan text block menghasilkan pola yang berguna untuk laporan pendek. Templatnya ditulis sebagai text block agar terbaca seperti keluarannya, lalu setiap barisnya dipotong dengan lines, diberi awalan, dan diberi bingkai yang panjangnya dihitung dengan repeat.

java LaporanBerbingkai.java
public class LaporanBerbingkai {

    public static void main(String[] args) {
        String templat = """
                Rekap nilai ujian
                Ali   : 92
                Budi  : 85
                Citra : 78
                """;

        String bingkai = "-".repeat(24);
        System.out.println(bingkai);
        for (String baris : templat.lines().toList()) {
            System.out.println(" " + baris.stripTrailing());
        }
        System.out.println(bingkai);
    }
}
text Keluaran
------------------------
 Rekap nilai ujian
 Ali   : 92
 Budi  : 85
 Citra : 78
------------------------

Metode stripTrailing yang dipakai di sini menghapus spasi di akhir baris saja dan membiarkan indentasi awalnya tetap, kebalikan dari stripLeading yang hanya membersihkan bagian depan. Pada templat tanpa spasi membuntuti, hasilnya sama dengan baris aslinya, tetapi pemanggilan itu tetap berguna sebagai penjaga ketika templat disunting dan tak sengaja menyisakan spasi di ujung barisnya.

Kesalahan umum#

  • Memeriksa baris dengan isEmpty padahal maksudnya menolak baris berisi spasi. String " " lolos dari isEmpty, sehingga baris hantu tetap terhitung. Ganti dengan isBlank.
  • Mengandalkan trim untuk teks yang mengandung spasi Unicode. Spasi seperti U+2002 tidak tersentuh trim dan tetap ikut ke dalam perbandingan. Pakai strip.
  • Memakai split("\n") untuk teks dari file Windows. Penanda \r\n menyisakan \r di akhir setiap baris, sehingga perbandingan string gagal tanpa pesan error. Metode lines menangani ketiga bentuk penanda baris sekaligus.
  • Memberi hitungan negatif pada repeat dari variabel yang belum diperiksa. Hasilnya IllegalArgumentException dengan pesan count is negative, dan perbaikannya membatasi hitungan dengan Math.max(0, hitungan).
  • Menganggap keluaran text block tanpa pindah baris di ujungnya. Selama tanda penutup """ berdiri sendiri, satu \n selalu melekat di akhir isi, dan lines memperlakukannya sebagai batas baris terakhir, bukan baris tambahan.

Ringkasan#

  • strip menghapus spasi tepi mengikuti Character.isWhitespace, sehingga lebih luas daripada trim yang berhenti di U+0020, sedangkan isBlank menolak string berisi spasi apa pun yang justru lolos dari isEmpty.
  • lines memecah string menjadi Stream<String> tanpa penanda baris dan mengenali \n, \r\n, serta \r, sehingga lebih andal daripada split("\n").
  • repeat menyusun pengulangan string untuk pemisah dan indentasi, dengan hitungan nol sah dan hitungan negatif melempar IllegalArgumentException.
  • Text block yang berpasangan dengan lines, strip, dan repeat menjadi pola pendek untuk membersihkan catatan dan menyusun laporan berbingkai.

Referensi#