Perulangan tidak selalu berhenti karena kondisinya berubah menjadi false. Pernyataan break menghentikan putaran di tengah jalan, continue melewati sisa satu putaran, dan keduanya dapat menunjuk sebuah label untuk mengendalikan perulangan yang bersarang. Topik ini membahas ketiganya melalui dua pola yang paling sering dipakai, yaitu berhenti saat target ditemukan dan melompati data yang tidak lolos syarat.
break menghentikan putaran lebih awal#
Di dalam badan perulangan, break langsung menghentikannya dan memindahkan eksekusi ke pernyataan setelah perulangan itu. Pemakaian yang paling umum adalah pencarian, karena memeriksa sisa data setelah target ketemu hanya memboroskan putaran.
public class CariAngka {
public static void main(String[] args) {
int[] data = {34, 12, 78, 5, 90, 23};
int target = 5;
int posisi = -1;
for (int i = 0; i < data.length; i++) {
if (data[i] == target) {
posisi = i;
break;
}
}
if (posisi != -1) {
System.out.println(target + " ditemukan pada indeks " + posisi);
} else {
System.out.println(target + " tidak ada di dalam array");
}
}
}5 ditemukan pada indeks 3Target 5 berada pada indeks 3, sehingga break menghentikan perulangan tanpa menyentuh 90 dan 23 di belakangnya. Variabel posisi tetap bernilai -1 bila perulangan berakhir dengan sendirinya, nilai penanda yang kemudian diuji untuk membedakan target ditemukan dan tidak. Tanpa break, program yang sama tetap benar, tetapi seluruh array diperiksa walaupun target sudah ketemu, dan selisihnya terasa pada data yang besar.
Karena itulah pencarian lurus hampir selalu ditulis dengan break di dalamnya. break tanpa label selalu berlaku pada perulangan terdalam yang mengapitnya, dan pernyataan yang sama juga menjadi penghenti cabang switch klasik. Kombinasi while (true) dengan break juga sah, lazim dipakai ketika kondisi berhentinya baru bermakna setelah sebagian badan dieksekusi, misalnya setelah membaca satu catatan data.
continue melompati satu putaran#
Pernyataan continue memotong sisa badan pada putaran itu dan langsung melanjutkan ke putaran berikutnya. Pada for, bagian pembaruan tetap dijalankan, sedangkan pada while pemeriksaan kondisinya yang langsung diulang, sehingga posisi pembaruannya menentukan apakah putaran maju atau macet.
public class SaringNilai {
public static void main(String[] args) {
int[] nilai = {72, 45, 88, 60, 39, 95};
int jumlahLulus = 0;
int totalLulus = 0;
for (int n : nilai) {
if (n < 60) {
continue;
}
jumlahLulus = jumlahLulus + 1;
totalLulus = totalLulus + n;
}
double rataRata = (double) totalLulus / jumlahLulus;
System.out.println("Lulus: " + jumlahLulus + " dari " + nilai.length + " nilai");
System.out.println("Rata-rata nilai lulus: " + rataRata);
}
}Lulus: 4 dari 6 nilai
Rata-rata nilai lulus: 78.75Nilai di bawah 60 dilewati continue, sehingga hanya 72, 88, 60, dan 95 yang masuk perhitungan, dan rata-ratanya 78.75. Pola ini disebut penyaringan, karena badan perulangan menaruh syarat lanjutannya di awal, lalu pekerjaan utamanya setelah syarat itu lolos. Diagram berikut merangkum arah lompatan keduanya dalam satu putaran.
Dari diagram itu terlihat bahwa continue tetap berada di dalam perulangan dan hanya melompat ke putaran berikutnya, sedangkan break benar-benar keluar dari perulangannya. Keduanya memotong satu bagian badan, bukan keseluruhan blok, sehingga pernyataan yang berada di bawah titik lompatannya tidak pernah dijalankan pada putaran itu.
Label untuk keluar dari perulangan bersarang#
Masalah muncul ketika yang perlu dihentikan adalah perulangan luarnya, sebab break biasa hanya memotong perulangan terdalam. Java menyediakan label, yaitu nama yang diakhiri titik dua dan diletakkan tepat sebelum pernyataan perulangan, lalu break dapat menyebut namanya untuk keluar sampai perulangan yang berlabel itu.
public class CariKursi {
public static void main(String[] args) {
boolean[][] terisi = {
{true, true, false},
{true, false, true},
{true, true, true}
};
int barisKetemu = -1;
int kolomKetemu = -1;
cari:
for (int baris = 0; baris < terisi.length; baris++) {
for (int kolom = 0; kolom < terisi[baris].length; kolom++) {
if (!terisi[baris][kolom]) {
barisKetemu = baris;
kolomKetemu = kolom;
break cari;
}
}
}
if (barisKetemu != -1) {
System.out.println("Kursi kosong ditemukan di baris " + barisKetemu + ", kolom " + kolomKetemu);
} else {
System.out.println("Semua kursi sudah terisi");
}
}
}Kursi kosong ditemukan di baris 0, kolom 2Label cari menempel pada perulangan baris, sehingga break cari di dalam perulangan kolom menghentikan keduanya sekaligus. Tanpa label, hanya perulangan kolom yang berhenti dan perulangan baris akan melanjutkan pencariannya, sehingga dibutuhkan bendera tambahan atau pengujian ganda agar berhenti total. continue juga menerima label, dan lompatannya menuju putaran berikutnya dari perulangan yang berlabel itu.
// tidak-dijalankan
cari:
for (int baris = 0; baris < data.length; baris++) {
for (int kolom = 0; kolom < data[baris].length; kolom++) {
if (data[baris][kolom] < 0) {
continue cari; // lompat ke baris berikutnya
}
}
System.out.println("Baris " + baris + " penuh bilangan non-negatif");
}Pada contoh di atas, satu nilai negatif di baris mana pun membuat baris itu tidak dicetak, karena continue cari melompat ke putaran baris berikutnya. Label tidak terbatas pada perulangan, karena dapat menempel pada blok pernyataan mana pun, tetapi pemakaiannya hampir selalu pada perulangan bersarang.
Kapan label layak dipakai#
Label tampil jarang di kode sehari-hari, dan yang paling sering terlihat adalah break berlabel untuk pencarian pada data dua dimensi, sebagaimana contoh kursi di atas. Bentuk yang lebih jarang lagi adalah continue berlabel, karena pola penyaringan biasanya cukup dijawab dengan syarat bersarang di dalam perulangan dalam.
Alternatif yang sering lebih jelas adalah memindahkan pencarian ke metode tersendiri dan kembali lewat return. Metode yang disebut cariKursiKosong cukup menjawab satu pertanyaan, posisinya dapat diuji terpisah, dan pembaca perulangan luarnya tidak perlu menelusuri lompatan lintas dua tingkat indentasi. Bila pencariannya pendek dan hanya dipakai sekali di tempat itu juga, break berlabel tetap sah dan lebih ringkas daripada membuat metode tambahan. Yang perlu dijaga hanyalah nama labelnya, yang sebaiknya berupa kata yang berarti seperti cari atau cariKursi, bukan huruf tunggal yang tidak menjelaskan tujuannya.
Kesalahan umum#
- Mengira satu
breakmenghentikan seluruh perulangan bersarang. Yang berhenti hanya perulangan terdalam yang mengapitnya, dan perulangan luarnya melanjutkan putarannya. - Menaruh
continuedi atas pembaruan padawhile, misalnya pengurangan penghitung. Pemeriksaan kondisi diulang tanpa pernah maju, dan perulangan berjalan tanpa akhir. - Mengharapkan
breakbiasa cukup untuk keluar dari perulangan luarnya, lalu menambah benderabooleanyang menyebar ke seluruh badan. Bila kondisi keluarnya berada di perulangan dalam, label atau pemecahan ke metode lebih ringkas. - Menyebut label dari luar blok yang berlabel atau menaruh label pada pernyataan yang tidak mengapit lompatannya. Kompiler menolak dengan pesan
undefined label, karena label hanya berlaku pada pernyataan yang ditandai oleh label itu. - Memakai
breakdi beberapa titik yang tersebar dalam satu perulangan. Kondisi keluarnya menjadi sulit dipastikan, dan menggabungkan keluar ke satu titik uji atau satu metode pencarian biasanya lebih terbaca.
Ringkasan#
breakmenghentikan perulangan terdalam yang mengapitnya, sedangkancontinuememotong sisa putaran lalu melanjutkan ke putaran berikutnya.- Label sebelum pernyataan perulangan memungkinkan
breakdancontinuemenyasar perulangan luarnya, berguna pada pencarian data bersarang. - Pola pemakaiannya yang paling lazim adalah berhenti saat target ditemukan dan melompati data yang tidak lolos syarat.
- Alternatif yang sering lebih jelas adalah memindahkan pencarian ke metode tersendiri dan kembali lewat
return.
Referensi#
- Branching Statements — Oracle Java Tutorials
— Panduan resmi
break,continue, dan label pada pernyataan lompat Java. - Chapter 14: Blocks, Statements, and Patterns — Oracle
— Spesifikasi pernyataan
breakbeserta bentuk berlabelnya pada JLS Java SE 21.