Data di dunia nyata kerap berbentuk dua dimensi: tabel perkalian, papan catur, matriks nilai, layar penuh karakter. Satu loop hanya bergerak satu arah, namun loop yang diletakkan di dalam loop lain menghasilkan gerakan dua arah — baris demi baris, dan kolom demi kolom di dalam tiap baris. Struktur ini, disebut nested loops, adalah fondasi semua pemrosesan berstruktur grid, dari pencetakan pola sederhana hingga algoritma pengurutan dan pencocokan teks. Chapter ini melatih pola dasarnya lewat tabel perkalian dan segitiga bintang, lalu membiasakan kita menghitung berapa banyak iterasi yang sebenarnya terjadi di balik layar.

Struktur Dasar Loop Bersarang #

Aturan mainnya satu kalimat: badan loop luar dieksekusi sekali per iterasinya, dan badan itu berisi loop dalam yang berjalan tuntas dari awal sampai akhir. Ilustrasinya seperti membaca halaman buku — untuk setiap baris (loop luar), mata bergerak dari kata pertama hingga kata terakhir (loop dalam), lalu pindah ke baris berikutnya dan mengulangi gerakan yang sama.

java Kerangka loop bersarang
for (int baris = 1; baris <= 3; baris++) {       // 3 iterasi luar
    for (int kolom = 1; kolom <= 4; kolom++) {   // 4 iterasi dalam, tiap baris
        System.out.print(baris + "," + kolom + " ");
    }
    System.out.println();                         // akhir baris
}

Kerangka di atas mencetak pasangan 1,1 1,2 1,3 1,4 lalu ganti baris, 2,1 2,2 2,3 2,4, lalu 3,1 ... 3,4 — total 3 × 4 = 12 eksekusi badan loop dalam. Perkalian inilah hukum pertama loop bersarang: jumlah iterasi terdalam adalah hasil kali panjang tiap tingkat, sehingga loop 100 × 100 berarti sepuluh ribu kali kerja.

Membangun Tabel Perkalian #

Tabel perkalian adalah contoh paling jernih karena isi selnya memang hasil kali indeksnya — baris * kolom:

public class TabelPerkalian {
    public static void main(String[] args) {
        System.out.println("    x |  1  2  3  4  5");
        System.out.println("------+--------------");

        for (int baris = 1; baris <= 5; baris++) {
            System.out.printf("%4d  |", baris);
            for (int kolom = 1; kolom <= 5; kolom++) {
                System.out.printf("%3d", baris * kolom);
            }
            System.out.println();
        }
    }
}

Output yang Dihasilkan:

text
    x |  1  2  3  4  5
------+--------------
   1  |  1  2  3  4  5
   2  |  2  4  6  8 10
   3  |  3  6  9 12 15
   4  |  4  8 12 16 20
   5  |  5 10 15 20 25

Mari kita bedah pembentukan satu barisnya, ambil baris ke-3:

  1. Baris 6 (for (int baris = 1; baris <= 5; baris++)): loop luar berjalan lima kali — sekali per baris tabel. Setiap iterasinya mencetak satu baris utuh.
  2. Baris 7 (System.out.printf("%4d |", baris);): nomor baris dicetak sekali di awal baris — berada di luar loop kolom agar tidak berulang. Format %4d menyediakan lebar empat karakter rata kanan.
  3. Baris 8-10 (for (int kolom = 1; kolom <= 5; kolom++)): loop dalam berjalan lima kali per baris; setiap iterasi mencetak satu sel dengan format %3d (lebar tiga, rata kanan) — angka 9 dan 15 rapi sejajar berkat lebar tetap ini.
  4. Baris 11 (System.out.println();): ganti baris diletakkan setelah loop kolom selesai — penempatan yang menentukan bentuk; bila dipindah ke dalam loop kolom, seluruh angka akan jatuh ke kolom tunggal vertikal.

Pola penempatan statement relatif terhadap dua loop inilah inti keterampilan loop bersarang: sebelum loop dalam = sekali per baris; di dalam loop dalam = sekali per sel; setelah loop dalam = sekali per baris di akhir.

Pola Segitiga Bintang #

Latihan kedua membentuk geometri: segitiga sama kaki dari karakter bintang. Kuncinya menemukan rumus hubungan antara nomor baris dan jumlah karakter yang dicetak — spasi makin berkurang, bintang makin bertambah:

public class PolaSegitiga {
    public static void main(String[] args) {
        int tinggi = 5;

        for (int baris = 1; baris <= tinggi; baris++) {
            // spasi di kiri: makin ke bawah makin sedikit
            for (int spasi = tinggi - baris; spasi >= 1; spasi--) {
                System.out.print(" ");
            }
            // bintang: 1, 3, 5, 7, 9 sesuai baris
            for (int bintang = 1; bintang <= 2 * baris - 1; bintang++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }
}

Output yang Dihasilkan:

text
    *
   ***
  *****
 *******
*********

Dua rumus kecil mengendalikan seluruh bentuk:

  1. Baris 7 (for (int spasi = tinggi - baris; spasi >= 1; spasi--)): baris ke-1 butuh 5 - 1 = 4 spasi, baris ke-2 butuh 3, …, baris ke-5 butuh 0 — loop spasi makin pendek seiring baris turun, mendorong bintang ke kiri membentuk puncak.
  2. Baris 11 (for (int bintang = 1; bintang <= 2 * baris - 1; bintang++)): jumlah bintang mengikuti bilangan ganjil berurutan 2 * baris - 1 — yaitu 1, 3, 5, 7, 9 — sehingga setiap baris bertambah dua bintang dan segitiga tumbuh simetris.
  3. Baris 14 (System.out.println();): penutup baris yang sama seperti tabel — di luar kedua loop karakter, di dalam loop baris.

Kedua loop dalam berbagi satu titik temu: keduanya memakai baris milik loop luar sebagai sumber rumus. Ketergantungan searah ini (loop dalam membaca variabel loop luar, tidak sebaliknya) menjaga logika tetap terurus — arah kebalikannya, loop luar yang membaca kolom, tidak masuk akal karena kolom bahkan belum lahir saat loop luar menguji kondisinya.

Menghitung Total Iterasi #

Hukum perkalian iterasi patut dihormati sejak awal. Tabel 5 × 5 kita mengeksekusi badan terdalam 25 kali — sepele; tabel 100 × 100 sudah sepuluh ribu; dan loop tiga tingkat 100 × 100 × 100 mencapai satu juta eksekusi. Struktur bersarang adalah cara termudah menulis program yang “tiba-tiba lambat”, karena pertumbuhan iterasinya berlipat, bukan bertambah. Kebiasaan sederhana untuk sekarang: sebelum menambah satu tingkat loop lagi, tanyakan apakah pekerjaan itu benar-benar membutuhkan kombinasi penuh — ataukah sebagian besar iterasi hanya akan berakhir di continue atau break. Pertanyaan serupa akan kita dalami secara formal pada Section Algorithms dan Data Structures dengan notasi Big-O.

Loop bersarang menuntaskan seperempat terakhir perkakas perulangan. Sebelum menutup section ini, ada satu topik penyatunya: bagaimana compiler javac menelusuri seluruh jalur yang mungkin dilalui statement-statement kita — cabang mana yang pernah memuat sebuah variabel, loop mana yang pasti berhenti, statement mana yang tak akan pernah terjangkau — dan menolak program yang jalurnya tidak memadai. Chapter pamungkas section ini membahas control flow analysis tersebut.

Referensi #

Berkas Sumber

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

PolaSegitiga.java

Unduh berkas
java
public class PolaSegitiga {
    public static void main(String[] args) {
        int tinggi = 5;

        for (int baris = 1; baris <= tinggi; baris++) {
            // spasi di kiri: makin ke bawah makin sedikit
            for (int spasi = tinggi - baris; spasi >= 1; spasi--) {
                System.out.print(" ");
            }
            // bintang: 1, 3, 5, 7, 9 sesuai baris
            for (int bintang = 1; bintang <= 2 * baris - 1; bintang++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }
}

TabelPerkalian.java

Unduh berkas
java
public class TabelPerkalian {
    public static void main(String[] args) {
        System.out.println("    x |  1  2  3  4  5");
        System.out.println("------+--------------");

        for (int baris = 1; baris <= 5; baris++) {
            System.out.printf("%4d  |", baris);
            for (int kolom = 1; kolom <= 5; kolom++) {
                System.out.printf("%3d", baris * kolom);
            }
            System.out.println();
        }
    }
}