3.
Loop dan Logika
Pada bab ini,
Anda akan belajar bagaimana membuat keputusan dan pilihan dalam program-program
Java. Anda juga akan belajar bagaimana membuat program Anda mengulangi sejumlah
aksi tertentu sampai kondisi spesifik terpenuhi. Pada bab ini, Anda akan
belajar:
ð
Bagaimana
membandingkan nilai-nilai data
ð
Bagaimana Anda
dapat mendefinisikan ekspresi logikal
ð
Bagaimana Anda
dapat menggunakan ekspresi logikal untuk mengubah urutan eksekusi statemen
ð
Bagaimana Anda
dapat memilih ekspresi tertentu, yang bergantung pada nilai dari ekspresi
logikal
ð
Bagaimana
memilih opsi tertentu dari sejumlah alternatif yang disediakan
ð
Berapa lama
variabel dapat diakses
ð
Bagaimana Anda
dapat mengeksekusi secara berulang atau merepetisi sebuah blok kode dengan
jumlah repitisi tertentu
ð
Bagaimana Anda
dapat merepetisi sebuah blok kode sepanjang ekspresi logikal bernilai true
Membuat Keputusan
Kemampuan
membuat keputusan merupakan elemen fundamental pada semua program Java. Anda
tentu ingin bisa membuat keputusan seperti, “Jika user ingin memasukkan data
lainnya, maka baca nilai tersebut dari papantik” atau “Jika saldo banyak, maka
beli mobil sport, kalau tidak beli tiket bus”. Apapun keputusan yang Anda
berikan, dalam dunia pemrograman, hal itu terkait dengan kemampuan dalam
membuat perbandingan antara variabel, konstanta, dan nilai ekspresi. Jadi,
langkah pertama yang penting dipahami dalam membuat keputusan pada sebuah
program adalah dengan belajar membuat perbandingan.
Membuat
Perbandingan
Java menyediakan
enam operator relasional untuk membandingkan dua nilai data. Nilai data yang
Anda bandingkan dapat berupa variabel, konstanta, atau ekspresi yang
menggunakan nilai-nilai bertipe data primitif seperti byte, short, int, long, char, float, dan double.
Operator Relasional
|
Penjelasan
|
>
|
Menghasilkan
nilai true jika operand kiri lebih
besar daripada operand kanan, sebaliknya menghasilkan false.
|
>=
|
Menghasilkan
nilai true jika operand kiri lebih
besar atau sama dengan daripada operand kanan, sebaliknya menghasilkan false.
|
==
|
Menghasilkan
nilai true jika operand kiri sama
dengan operand kanan, sebaliknya menghasilkan false.
|
!=
|
Menghasilkan
nilai true jika operand kiri tidak
sama dengan operand kanan, sebaliknya menghasilkan false.
|
<=
|
Menghasilkan
nilai true jika operand kiri lebih
kecil atau sama dengan operand kanan, sebaliknya menghasilkan false.
|
<
|
Menghasilkan
nilai true jika operand kiri lebih
kecil daripada operand kanan, sebaliknya menghasilkan false.
|
Seperti yang
Anda lihat, setiap operand menghasilkan nilai true atau false, jadi
ini cocok dengan urusan pembuatan keputusan. Ini mengimplikasikan bahwa Anda
dapat menggunakan variabel boolean
untuk menyimpan hasil perbandingan. Anda telah melihat bagaimana
mendeklarasikan variabel bertipe boolean
pada bab terdahulu. Misalnya, Anda dapat mendefinisikan sebuah variabel boolean, keadaan, dan menetapkan nilainya menjadi hasil dari sebuah ekspresi
yang menggunakan perbandingan berikut:
boolean keadaan = false; // Mendefinisikan dan menginisialisasi
variabel
keadaan = x – y < a + b; // Menyimpan hasil perbandingan x-y
dengan a+b
Nilai dari
variabel keadaan akan ditetapkan true
pada statemen penugasan jika x – y bernilai kurang dari a + b, dan menjadi false jika tidak.
Untuk memahami
bagaimana ekspresi tersebut dievaluasi, lihat kembali tabel keutamaan operator
yang telah didiskusikan pada bab sebelumnya. Anda akan melihat bahwa
operator-operator perbandingan memiliki keutamaan lebih rendah daripada
operator-operator aritmatik, sehingga operator-operator aritmatik akan selalu
dieksekusi lebih dahulu daripada operator-operator perbandingan, kecuali jika
ada tanda kurung yang mengubah urutan eksekusi. Ekspresi
x – y == a + b
akan memberikan
hasli true jika x – y sama dengan a
+ b, karena sub-subekspresi aritmatik akan dievaluasi lebih dahulu, dan
nilai-nilainya akan menjadi operand-operand untuk operator ==. Tentu, Anda bisa
menggunakan tanda-kurung, meskipun hal itu tidak akan mengubah hasilnya, tetapi
dapat memperjelas makna bagi pembaca:
(x – y) == (a + b)
Perhatikan jika
operand kiri dan operand kanan dari operasional relasional memiliki tipe data
yang berbeda, maka nilai-nilai akan dipromosi dengan cara sama seperti yang
Anda lihat pada bab sebelumnya untuk ekspresi aritmatik campuran atau gabungan.
Jadi, jika aDouble merupakan
variabel bertipe double dan angka adalah variabel bertipe int pada ekspresi berikut:
aDouble < angka + 1;
maka hasil
ekspresi angka + 1 akan dihitung
sebagai tipe int, dan nilai ini akan
dipromosikan (dikonversi tipe secara implisit) menjadi tipe double sebelum perbandingan dilakukan
dengan nilai dari aDouble.
Statemen
if
Statemen if, pada konfigurasi sederhananya,
memiliki bentuk:
if(ekspresi)
statemen;
dimana ekspresi
dapat berupa sembarang ekspresi yang menghasilkan nilai true atau false. Anda
dapat melihat representasi grafikal dari logika ini pada Gambar 3-1.
Gambar 3-1
Jika nilai dari
ekspresi bernilai true, maka
statemen yang mengikuti if akan
dieksekusi, sebaliknya, tidak. Contoh praktisnya diberikan berikut:
if(angka%2 !=0) // Menguji apakah angka adalah
ganjil
++angka; //
Jika ya, buat angka menjadi genap
Kondisi if yang diapit tanda-kurung menguji
apakah angka bernilai ganjil dengan
membandingkan sisa pembagian 2 atas angka
dengan 0. Jika sisa tidak sama dengan 0, maka angka bernilai ganjil, jadi 1 akan ditambahkan pada angka. Jika angka bernilai genap, statemen yang menginkremen angka tidak akan dieksekusi.
Anda kadangkala
akan melihat sebuah if sederhana yang dituliskan pada satu baris kode. Contoh
di atas dapat dituliskan menjadi:
if(angka%2 !=0) ++angka; // jika angka ganjil, dibuat genap
Hal ini sah
dalam Java. Kompilator akan mengabaikan karakter spasi dan baris-baru.
Titik-koma berperan sebagai pembatas statemen. Penulisan if dengan cara ini akan menghemat ruang penulisan, dan kadangkala
dapat memperjelas pembacaan kode.
Blok Statemen
Anda bisa
menciptakan sebuah blok statemen yang diapit dengan simbol kurung-kurawal. Anda
bisa menciptakan sebuah blok statemen di dalam statemen if, seperti berikut:
if(ekspresi) {
statemen 1;
statemen 2;
…
statemen n
}
Sekarang, jika
nilai dari ekspresi bernilai true, maka semua statemen yang
bersarang di dalam blok tersebut akan dieksekusi. Tentu, tanpa kurung-kurawang,
kode tidak lagi memiliki blok statemen:
if(ekspresi)
statemen 1;
statemen 2;
…
statemen n
Di sini, hanya
statemen pertama, statemen 1, yang
akan diabaikan jika ekspresi
bernilai false; statemen-statemen
lain akan selalu dieksekusi tanpa memandang nilai dari ekspresi. Anda dapat melihat dari sini bahwa indentasi (penataan
atau pemosisian statemen) hanyalah bantuan visual, yang tidak berpengaruh
terhadap bagaimana kode program dieksekusi. Runtun statemen tersebut memang
tampak menjadi bagian dari if,
tetapi hanya statemen pertama yang menjadi bagian dari if, karena ketiadaan kurung-kurawal.
Sebagai contoh
praktis dari statemen if yang memuat
sebuah blok statemen, Anda bisa menuliskan:
if(angka%2 != 0) { // Menguji apakah angka bernilai ganjil
// jika ya, jadikan genap dan tampilkan
pesan
++angka;
System.out.println(“Angka dipaksa menjadi
genap dan sekarang “ + angka);
}
Sekarang kedua
statemen yang ada di dalam kurung-kurawal akan dieksekusi jika ekspresi dari statemen if bernilai true, dan kedua statemen tersebut tidak akan dieksekusi jika ekspresi bernilai false.
Klausa else
Anda dapat
mengembangkan statemen if dasar
dengan memanfaatkan klausa else. Ini
memberikan statemen atau blok statemen alternatif, yang akan dieksekusi ketika ekspresi pada statemen if bernilai false. Anda dapat melihat sintaksis dari statemen ini, dan
bagaimana kendali program mengalir pada Gambar 3-2.
Mekanisme ini
memberikan pilihan eksplisit antara dua aksi: satu ketika ekspresi dari statemen if
bernilai true; dan lainnya ketika
bernilai false.
Anda dapat
menerapkannya pada program konsol dan mencoba metode random() dari kelas Math
pada saat yang sama.
Latihan
|
if-else
|
Ketika Anda
telah menuliskan program ini, simpan dan berikan nama PeriksaAngka.java. Kompilasi program tersebut dan jalankan beberapa
kali untuk melihat hasilnya.
public class PeriksaAngka {
public static void main(String[] args) {
int angka = 0;
// Mendapatkan sebuah integer acak antara
1 & 100
angka = 1+(int)(100*Math.random());
if(angka%2 == 0) { // Menguji apakah
genap
System.out.println("Anda mendapatkan
angka genap, " + angka); // genap
} else {
System.out.println("Anda
mendapatkan angka ganjil, " + angka); // ganjil
}
}
}
Gambar 3-2
Penjelasan
Anda telah
melihat metode random() yang
didefinisikan pada kelas Math pada
bab sebelumnya. Metode ini menghasilkan sebuah nilai acak bertipe double antara 0.0 dan 1.0, tetapi
hasilnya selalu kurang dari 1.0, jadi nilai terbesar yang mungkin Anda dapatkan
adalah 0.9999…. Konsekuensinya, ketika Anda mengalikan nilai yang dihasilkan
metode ini dengan 100.0 dan mengkonversi nilai ini menjadi tipe int dengan
konversi tipe eksplisit, maka Anda akan membuang bagian pecahannya dan sebuah
integer acak antara 0 dan 99 akan dihasilkan. Penambahan 1 menyebabkan integer
acak yang dihasilkan menjadi antara 1 dan 100, yang kemudian disimpan pada
variabel angka. Anda kemudian
menampilkan keluaran pada statemen if.
Jika nilai angka adalah genap, maka statemen println() pertama yang akan dieksekusi; sebaliknya, println() kedua pada klausa else yang dieksekusi.
Statemen
if Bersarang
Statemen yang
dieksekusi ketika ekspresi pada
statemen if bernilai true dapat pula berupa statemen if lain. Hal ini berlaku pula pada
klausa else. Sebuah statemen if dapat bersarang atau ditempatkan di
dalam statemen if lain. Untuk
mengilustrasikan statemen if
bersarang, Anda perlu memodifikasi if
dari contoh sebelumnya:
if(angka%2 == 0) { //
Menguji apakah genap
if(angka < 50) {
System.out.println("Anda mendapatkan
angka genap, " + angka); // genap
}
} else {
System.out.println("Anda mendapatkan
angka ganjil, " + angka); // ganjil
}
Sekarang pesan
untuk nilai genap akan ditampilkan hanya jika nilai dari angka kurang dari 50. Ada tiga kemungkinan yang terjadi pada
fragmen kode ini: jika angka bernilai
genap dan kurang dari 50, maka Anda akan melihat pesan terkait hal itu; jika angka bernilai genap dan tidak kurang
dari 50, maka tidak ada pesan yang ditampilkan; dan terakhir, jika angka bernilai ganjil, maka pesan
terkait angka ganjil akan ditampilkan.
Kurung-kurawal
yang mengapit if bersarang
diperlukan di sini karena adanya klausa else.
Kurung-kurawal tersebut mengekang if
bersarang. Jika kurung-kurawal tersebut tidak diberikan, program masih dapat
dikompilasi, tetapi logika program akan berbeda. Anda akan melihatnya sekarang.
Dengan adanya if bersarang, pertanyaan tentang kepada
statemen if manakah klausa else tertentu melekat sering muncul.
Jika Anda menghapus kurung-kurawal dari kode di atas, Anda memiliki:
if(angka%2 == 0) // Menguji apakah genap
if(angka < 50)
System.out.println("Anda mendapatkan
angka genap, " + angka); // genap
else
System.out.println("Anda mendapatkan
angka ganjil, " + angka); // ganjil
Ini akan
mengubah logika program dari versi sebelumnya, meskipun indentasi (penataan
kode) mengimplikasikan sebaliknya. Klausa else
sekarang melekat ke if bersarang
yang menguji apakah angka bernilai
kurang dari 50, jadi pemanggilan println()
dieksekusi hanya untuk angka-angka genap yang lebih besar atau sama dengan
50. Ini jelaslah berbeda dengan logika sebelumnya.
Latihan
|
Mendekripsi
Karakter
|
Ciptakanlah
kelas PeriksaHuruf, dan tuliskan
kode pada metode main() seperti
berikut:
public class PeriksaHuruf {
public static void main(String[] args) {
char simbol = 'A';
// Membangkitkan sebuah karakter acak
simbol = (char)(128.0*Math.random());
if(simbol >= 'A') { // Apakah huruf A atau
lebih besar?
// ya, apakah kurang dari atau sama
dengan Z?
if(simbol <= 'Z') {
// Berarti huruf besar
System.out.println("Anda
memiliki huruf besar " + simbol);
} else { // Tidak kurang dari atau
sama dengan Z
// Apakah sama dengan atau lebih
besar dari a?
if(simbol >= 'a') {
// Ya, apakah kurang dari atau
sama dengan z?
if(simbol <= 'z') {
// Jadi ia adalah huruf kecil
System.out.println("Anda
memiliki huruf kecil " + simbol);
} else { // Tidak kurang dari z
System.out.println(
"Kode lebih besar dari a tetapi bukan huruf");
}
} else {
System.out.println(
"Kode kurang dari a dan
bukan huruf");
}
}
} else {
System.out.println("Kode kurang
dari A dan bukan huruf");
}
}
}
Penjelasan
Program ini
mencari-tahu apakah karakter yang disimpan pada variabel simbol adalah huruf
besar, huruf kecil, atau karakter lain. Program ini lebih dahulu membangkitkan
sebuah karakter acak dengan kode numerik antara 0 dan 127, yang berkaitan
dengan karakter-karakter pada himpunan karakter ASCII 7-bit (ISO 646).
Pengkodean Unicode untuk karakter-karakter ASCII secara numerik sama dengan
nilai-nilai kode ASCII. Pada himpunan karakter ini, huruf ‘A’ sampai ‘Z’
direpresentasikan secara berurutan dengan nilai desimal 65 sampai 90.
Huruf-huruf kecil direpresentasikan secara berurutan dengan nilai-nilai kode
ASCI yang memiliki nilai desimal 97 sampai 122. Jadi, untuk mengkonversi huruf
kecil menjadi huruf besar, Anda perlu menambahkan 32 pada kode karakter.
Statemen-statemen
if sedikit sulit dipahami, seperti
pada diagam logika pada Gambar 3-3.
Anda memiliki
empat statemen if. Statemen if pertama menguji apakah simbol adalah ‘A’ atau lebih besar.
Jika ya, ia bisa jadi berupa huruf besar, huruf kecil, atau karakter lain.
Tetapi jika tidak, maka ia pasti bukan huruf, jadi klausa else untuk statemen if
ini (di akhir program) menghasilkan pesan yang berkaitan dengan itu.
Statemen if bersarang, yang dieksekusi jika simbol adalah ‘A’ atau lebih besar,
menguji apakah simbol adalah ‘Z’ atau lebih kecil. Jika ya, maka simbol pasti memuat huruf besar, dan
pesan tertentu akan ditampilkan. Jika tidak, maka simbol bisa jadi memuat huruf kecil, jadi statemen if lain dibuat bersarang di dalam
klausa else dari statemen if bersarang pertama untuk menguji
kemungkinan ini.
Gambar 3-3
Statemen if pada klausa else menguji apakah simbol
lebih besar dari ‘a’. Jika tidak, maka Anda mengetahui bahwa simbol bukanlah sebuah huruf, dan
sebuah pesan akan ditampilkan. Jika ya, maka if yang lain akan memeriksa apakah simbol adalah ‘z’ atau lebih kecil. Jika ya, maka simbol pastilah sebuah huruf kecil, dan
jika tidak, maka ia bukanlah sebuah huruf.
Membandingkan
Nilai-Nilai Enumerasi
Anda tidak bisa
membandingkan variabel bertipe enumarasi menggunakan operator-operator
perbandingan, tetapi Anda bisa melakukannya menggunakan sebuah metode yang
disediakan bagi semua objek enumerasi. Dimisalkan bahwa Anda mendefinisikan
sebuah tipe enumerasi:
enum Musim {semi, panas, gugur,
dingin}
Anda sekarang
dapat mendefinisikan dan menginisialisasi sebuah variabel bertipe Musim dengan statemen berikut:
Musim musim = Musim.panas;
Jika nantinya
Anda ingin memeriksa apakah yang sedang dimuat di dalam variabel musim, Anda bisa menuliskan:
if(musim.equals(Musim.panas)
{
System.out.println(“Musim panas telah
dimulai, rerumputan beranjak hijau.”);
} else {
System.out.println(“Sekarang belum masuk
musim panas!”);
}
Ini akan
memanggil metode equals() untuk
enumerasi yang diakses oleh musim.
Metode ini akan membandingkan nilai pada musim
dengan argumen metode dan menghasilkan true
apabila keduanya sama atau false
jika tidak sama. Anda dapat menggunakan metode equals() untuk membandingkan musim
dengan variabel lain bertipe Musim,
misalnya:
Musim terbaik =
Musim.dingin; // Sebuah variabel baru
diinisialisasi dengan dingin
if(musim.equals(terbaik) {
System.out.println(“Musim terbaik adalah
musim “ + terbaik);
} else {
System.out.println(“Variabel musim memiliki
nilai “ + musim +
“ dan variabel terbaik
memiliki nilai “ + terbaik);
}
Setelah
mendefinisikan variabel terbaik,
Anda menguji apakah nilai dari musim
sama dengan nilai dari terbaik. Jika ya, statemen keluaran pertama yang
dieksekusi. Jika terbaik dan musim bernilai tidak sama, maka
statemen keluaran pada blok else
yang akan dieksekusi.
Operator-Operator Logikal
Pengujian yang
Anda tempatkan pada ekspresi dari statemen if
sejauh ini relatif sederhana. Kehidupan nyata umumnya cukup kompleks. Anda akan
sering melakukan penggabungan sejumlah kondisi sehingga Anda akan mengeksekusi
statemen tertentu, misalnya, jika semua kondisi bernilai true secara bersamaan.
Anda bisa
memakai operator-operator logikal untuk menggabungkan sejumlah ekspresi yang
memiliki nilai true atau false. Karena setiap operator ini
diterapkan pada nilai boolean, maka operator-operator ini juga dikenal sebagai
operator boolean. Ada lima operator
logikal yang dapat diterapkan pada nilai boolean:
Simbol
|
Nama Panjang
|
&
|
AND logikal
|
&&
|
AND
kondisional
|
|
|
OR logikal
|
||
|
OR kondisional
|
!
|
Negasi logikal
(NOT)
|
Setiap operator
ini cukup sederhana; satu-satunya potensi kebingungan adalah fakta bahwa Anda
memiliki dua pilihan operator untuk tiap AND dan OR, yang akan dijelaskan
sebentar lagi.
Operasi-Operasi AND Logikal
Anda dapat
menggunakan operator AND, && dan &, dimana Anda memiliki dua
ekspresi logikal yang harus bernilai true
agar hasil bernilai true. Kedua operator AND tersebut akan memberikan
hasil yang sama. Pertama, Anda perlu mengetahui bagaimana keduanya digunakan.
Semua diskusi berikut dapat diterapkan pada kedua operator AND tersebut.
Anda akan
melihat bagaimana operator logikal dapat menyederhanakan contoh yang terakhir
diberikan. Anda dapat menggunakan operator & dan && jika Anda
menguji sebuah variabel bertipe char
untuk menentukan apakah ia memuat huruf besar atau tidak. Nilai yang sedang
diuji harus lebih besar dari atau sama dengan ‘A’ dan kurang dari atau sama
dengan ‘Z’. Kedua kondisi harus bernilai true
agar nilai adalah sebuah huruf besar. Dengan mengambil contoh dari program
sebelumnya, dengan sebuah nilai disimpan pada variabel char, simbol, Anda dapat
mengimplementasikan pengujian huruf besar dengan satu if menggunakan operator &&:
if(simbol >= ‘A’
&& simbol <= ‘Z’)
System.out.println(“Anda memiliki huruf
besar “ + simbol);
Jika Anda
melihat tabel keutamaan operator pada Bab 2, Anda akan mengetahui bahwa
operator-operator relasional akan dieksekusi sebelum operator &&, jadi
tidak diperlukan tanda kurung di sini. Di sini, statemen keluaran akan
dieksekusi hanya jika kedua kondisi yang dikombinasikan oleh operator
&& bernilai true. Namun,
adalah hal baik jika Anda menambahkan tanda-kurung untuk membuat kode lebih
mudah dibaca.
Latihan
|
Mendekripsi
Karakter Dengan Mudah
|
Anda dapat
mengganti mekanisme if-else terluar
dan isinya pada PeriksaHuruf.java
seperti ditampilkan berikut:
public class PeriksaHuruf2 {
public static void main(String[] args) {
char simbol = 'A';
// Membangkitkan sebuah karakter acak
simbol = (char)(128.0*Math.random());
// Apakah huruf besar?
if(simbol >= 'A' && simbol
<= 'Z') {
System.out.println("Anda memiliki
huruf besar " + simbol);
} else {
//
Apakah huruf kecil?
if(simbol >= 'a' && simbol
<= 'z') {
System.out.println("Anda
memiliki huruf kecil " + simbol);
} else { // Kurang dari z
System.out.println("Kode
bukanlah sebuah huruf");
}
}
}
}
Keluaran program
sama seperti versi kode sebelumnya.
Penjelasan
Penggunaan
operator && cukup memadatkan dan meringkaskan kode. Anda sekarang dapat
melakukan pekerjaan ini hanya dengan dua if,
dan hal itu lebih mudah untuk dimengerti.
Anda perlu
mengetahui bahwa ketika statemen pada klausa else adalah sebuah if,
maka statemen if tersebut tersebut
dapat ditempatkan pada baris yang sama dengan else, seperti pada:
// Apakah huruf besar?
if(simbol >= 'A' && simbol <= 'Z') {
System.out.println("Anda
memiliki huruf besar " + simbol);
} else if(simbol >= 'a'
&& simbol <= 'z') { // Apakah huruf kecil?
System.out.println("Anda
memiliki huruf kecil " + simbol);
} else { // Kurang dari z
System.out.println("Kode
bukanlah sebuah huruf");
}
& versus &&
Jadi, apa
perbedaan && dari &? Perbedaaan antara keduanya adalah bahwa
kondisional && tidak akan perlu mengevaluasi operand sebelah-kanan
apabila operand sebelah-kirinya bernilai false,
karena hasilnya sudah pasti bernilai false.
Ini akan membuat kode sedikit lebih cepat ketika operand sebelah-kiri bernilai false.
Sebagai contoh,
perhatikan statemen-statemen berikut:
int angka = 50;
if(angka<40 &&
(3*angka – 27)>100) {
System.out.println(“Angka = “ + angka);
}
Di sini,
ekspresi (3*angka – 27)>100 tidak
akan pernah dieksekusi karena ekspresi angka<40
selalu bernilai false. Di sisi lain,
jika Anda menuliskan statemen sebagai:
int angka = 50;
if(angka<40 &
(3*angka – 27)>100) {
System.out.println(“Angka = “ + angka);
}
Efeknya berbeda.
Keseluruhan ekspresi logikal selalu dievaluasi, jadi meskipun operand sisi-kiri
dari operator & bernilai false
dan hasilnya sudah pasti false,
operand sebelah-kiri (3*angka –
27)>100 akan selalu dievaluasi.
Jadi, Anda dapat
menggunakan && setiap waktu untuk membuat program Anda sedikit lebih
kencang dan melupakan & selamanya? Salah, semua tergantung apa yang sedang
Anda lakukan. Hampir pada semua kasus Anda dapat menggunakan &&, tetapi
ada beberapa kasus lain ketika Anda ingin memastikan agar operand sebelah-kanan
tetap dieksekusi.
Misalnya,
terdapat keadaan dimana ekspresi sisi-kanan melibatkan pemodifikasian sebuah
variabel, dan Anda menginginkan variabel itu dimodifikasi pada setiap waktu:
if(++nilai%2 == 0 &
++cacah < batas) {
// Lakukan sesuai
}
Di sini,
variabel cacah akan diinkremen
setiap waktu. Jika Anda menggunakan && menggantikan &, cacah hanya akan diinkremen jika
operand sisi-kiri dari operator AND bernilai true. Anda akan mendapatkan hasil berbeda tergantung dari operator
mana yang digunakan.
Perhatikan kasus
kedua berikut:
if(cacah > 0 &&
total/cacah > 5) {
// Lakukan sesuatu
}
Pada kasus ini,
operand sisi-kanan untuk operasi && akan dieksekusi hanya jika operand
kiri bernilai true, yaitu ketika cacah bernilai positif. Jelaslah, jika
Anda menggunakan & di sini, dan cacah
ternyata bernilai 0, maka Anda akan mencoba melakukan pembagian nilai total dengan 0, yang akan menghentikan
program.
Operasi-Operasi OR Logikal
Operator OR, |
dan ||, dapat diterapkan ketika Anda menginginkan hasil true jika salah satu atau kedua operand bernilai true. OR logikal, ||, memiliki efek
mirip seperti pada AND logikal, yaitu mengabaikan evaluasi terhadap operand
sisi-kanan ketika operand sisi-kiri bernilai true. Jika operand sisi-kiri bernilai true, hasilnya pasti akan bernilai true tanpa memandang apakah operand sisi-kanan bernilai true atau false.
Ambil sebuah
contoh. Sebuah tiket diskon untuk masuk kebun binatang akan diberikan bagi
mereka yang berusia di bawah 16 tahun atau bagi mereka yang berusia lebih dari
atau sama dengan 65 tahun. Ini dapat diuji menggunakan statemen if berikut:
if(usia < 16 || usia
>= 65) {
hargaTiket = *= 0.9; // Harga tiket didiskon 10%
}
Efeknya di sini
adalah untuk memberikan diskon 10% pada hargaTiket
jika salah satu kondisi bernilai true.
Jelaslah pada kasus ini, kedua kondisi tidak bisa bernilai true.
Pada operasi |
atau ||, Anda akan mendapatkan hasil false
hanya jika kedua operand bernilai false.
Jika salah satu atau kedua operand bernilai true, maka hasil yang didapatkan adalah true.
Operasi NOT Boolean
Tipe ketiga dari
operator logikal, !, diterapkan pada satu operand boolean, dan hasilnya adalah kebalikan dari nilai operand. Jadi,
jika nilai dari sebuah variabel boolean,
keadaan, bernilai true, maka ekspresi !keadaan memiliki nilai false, dan sebaliknya jika keadaan bernilai false, maka !keadaan
akan bernilai true.
if(!(usia >= 16 &&
usia < 65) {
hargaTiket = *= 0.9; // Harga tiket didiskon 10%
}
Ekspresi (usia >= 16 && usia < 65)
bernilai true jika usia dari 16
sampai 64. Mereka yang berusia seperti ini tidak akan diberikan diskon, jadi
diskon hanya diterapkan ketika ekspresi ini bernilai false. Dengan menerapkan operator ! pada hasil ekspresi ini, Anda
dapat mencapai tujuan ini, yaitu mereka yang berusia seperti ini tidak akan
diberikan diskon.
Anda juga dapat
menerapkan operator ! pada sebuah ekspresi yang merupakan favorit dari Charles
Dickens:
!(pendapatan >
pengeluaran)
Jika ekspresi
ini bernilai true, maka hasilnya adalah kesengsaraan, paling tidak ketika
menyita rumah atau barang berharga Anda.
Tentu, Anda
dapat mengkombinasikan semua operator logikal, jika diperlukan. Jika sebuah
kebun binatang memutuskan untuk memberikan diskon tiket masuk kepada mereka
yang berusia di bawah 12 tahun dan dengan tinggi badan 148 cm, atau kepada
mereka yang berusia di atas 65 tahun dengan tinggi badan 172 cm, maka Anda
dapat menerapkan diskon dengan menerapkan pengujian ini:
if((usia > 12 &&
tinggi < 148) || (usia > 65 && tinggi >172)) {
hargaTiket *= 0.8; // 20 % diskon pada harga tiket
}
Tanda-kurung
sebenarnya tidak diperlukan di sini, karena operator && memiliki
keutamaan lebih tinggi daripada ||, tetapi penambahan tanda-kurung akan
memperjelas bagaimana perbandingan-perbandingan dilakukan.
Pengujian Karakter Menggunakan Metode-Metode Pustaka
Standar
Meskipun
pengujian karakter menggunakan operator logikal merupakan cara
mendemonstrasikan bagaimana operator-operator logikal digunakan, tetapi pada
prakteknya ada cara yang lebih mudah. Paket-paket standar Java menyediakan
sejumlah metode standar untuk melakukan sejumlah pengujian karakter seperti
huruf atau dijit, yang telah Anda lakukan menggunakan statemen if. Semua metode tersebut tersedia pada
kelas Character, yang secara
otomatis tersedia bagi program Anda. Misalnya, Anda dapat menuliskan statemen if pada program PeriksaHuruf2 seperti ditunjukkan pada contoh berikut:
Latihan
|
Mendekripsi
Karakter Dengan Mudah
|
Pada contoh
berikut, ekspresi-ekspresi if pada main() yang ada pada PeriksaHuruf2 digantikan dengan
ekspresi-ekspresi yang memanggil metode-metode pada kelas Character:
import static
java.lang.Character.isLowerCase;
import static
java.lang.Character.isUpperCase;
public class PeriksaHuruf3 {
public static void main(String[] args) {
char simbol = 'A';
// Membangkitkan sebuah karakter acak
simbol = (char)(128.0*Math.random());
if(isUpperCase(simbol)) {
System.out.println("Anda memiliki
huruf besar " + simbol);
} else {
if(isLowerCase(simbol)) {
System.out.println("Anda
memiliki huruf kecil " + simbol);
} else {
System.out.println("Kode bukan
huruf");
}
}
}
}
Penjelasan
Karena Anda
memiliki dua statemen import untuk
metode isUpperCase dan isLowerCase di awal file sumber, Anda
dapat menggunakan kedua metode tersebut tanpa perlu menyebutkan nama kelas Character. Metode isUpperCase() menghasilkan true
jika nilai char yang Anda lewatkan
kepada metode itu adalah huruf besar, dan false
jika tidak. Sama halnya, metode isLowerCase()
menghasilkan true jika nilai char yang Anda lewatkan kepada metode
itu adalah huruf kecil, dan false
jika tidak.
Tabel berikut
menunjukkan sejumlah metode lain yang disediakan pada kelas Character yang bisa Anda pakai untuk
menguji karakter. Pada tiap kasus, Anda memberikan argumen bertipe char yang akan diuji kepada metode.
Metode
|
Penjelasan
|
isDigit()
|
Menghasilkan true jika argumen adalah sebuah dijit
(0 sampai 9), dan false jika
tidak.
|
isLetter()
|
Menghasilkan true jika argumen adalah sebuah
huruf, dan false jika tidak.
|
isLetterOrDigit()
|
Menghasilkan true jika argumen adalah huruf atau
dijit, dan false jika tidak.
|
isWhiteSpace()
|
Menghasilkan true jika argumen adalah spasi putih,
dan false jika tidak. Berikut
adalah karakter-karakter spasi putih: Space (‘ ‘), Tab (‘\t’), Newline
(‘\n’), Carriage Return (‘\r’), Form Feed (‘\f’).
|
Operator Kondisional
Operator
kondisional juga dikenal dengan operator ternary karena ia melibatkan tiga
operand. Cara memahaminya lebih baik dengan mempelajari contoh. Dimisalkan
bahwa Anda memiliki dua variabel bertipe int
dengan nama usiaAnda dan usiaSaya, dan Anda ingin menugaskan
nilai terbesar dari nilai-nilai tersimpan pada usiaAnda dan usiaSaya ke
dalam variabel ketiga, lebihTua,
yang juga bertipe int. Anda dapat
melakukannya dengan statemen berikut:
lebihTua = usiaAnda >
usiaSaya ? usiaAnda : usiaSaya;
Operator kondisional
memiliki sebuah ekspresi logika sebagai operand pertamanya. Pada kasus ini,
operand pertamanya adalah usiaAnda >
usiaSaya. Jika ekspresi ini bernilai true,
maka operand yang ada setelah simbol ?, pada kasus ini usiaAnda, akan dievaluasi untuk memberkan hasil dari operasi. Jika
ekspresi usiaAnda > usiaSaya
bernilai false, maka operand ketiga
yang ada setelah simbol :, pada kasus ini usiaSaya,
akan dievaluasi menjadi hasil dari operasi. Nilai hasil kemudian disimpan pada
variabel lebihTua. Kegunaan dari
operator kondisional pada statemen penugasan ini ekivalen dengan statemen if:
if(usiaAnda > usiaSaya) {
lebihTua = usiaAnda;
} else {
lebihTua = usiaSaya;
}
Ingat, meskipun
operator kondisional adalah sebuah operator, bukan statemen, Anda dapat menggunakannya
pada sebuah ekspresi yang lebih kompleks yang melibatkan operator-operator
lain. Operator kondisional dapat digeneralisir menjadi:
ekspresi_logikal ?
ekspresi1: ekspresi2;
Jika ekspresi_logikal dievaluasi true, hasil operasi adalah nilai dari ekspresi1, dan jika ekspresi_logikal dievaluasi false, hasilnya adalah nilai dari ekspresi2.
Latihan
|
Kondisional
|
Ketiklah kode
berikut, yang menambahkan ‘topi’ di akhir kalimat tergantung dari berapa banya
topi yang Anda miliki:
public class OperatorKondisional
{
public static void main(String[] args) {
int nTopi = 1; // Banyak topi
System.out.println("Saya memiliki " + nTopi + " topi" + (nTopi == 1 ?
"." : "-topi."));
nTopi++; // Menginkremen banyak topi
System.out.println("Saya memiliki " + nTopi + " topi" + (nTopi == 1 ?
"." : "-topi."));
}
}
Keluaran program:
Saya memiliki 1 topi.
Saya memiliki 2 topi-topi.
Penjelasan
Hasil eksekusi
atas operator kondisional pada program di atas adalah sebuah string yang memuat
sebuah titik ketika nilai dari nTopi
adalah 1, atau sebuah string yang memuat “-topi.” untuk kasus-kasus lain.
Efeknya adalah menyebabkan statemen keluaran untuk secara otomatis mengubah
keluaran antara singular dan plural.
Statemen switch
Anda menggunakan
statemen switch untuk memilih salah
satu dari sejumlah pilihan berdasarkan nilai ekspresi. Ekspresi harus
menghasilkan sebuah nilai bertipe integer selain long atau sebuah nilai bertipe enumerasi. Jadi, ekspresi yang
mengendalikan statemen switch dapat
menghasilkan sebuah nilai bertipe char,
byte, short, int, atau
konstanta enumerasi.
Berikut adalah
salah satu contoh statemen switch:
switch(cuci) {
case 1: //
cuci bernilai 1 untuk Katun
System.out.println(“Katun dipilih”);
break;
case 2: //
cuci bernilai 2 untuk Linen
System.out.println(“Linen dipilih”);
break;
case 3: //
cuci bernilai 3 untuk Wol
System.out.println(“Wol dipilih”);
break;
default: //
cuci tidak valid
System.out.println(“Error pemilihan”);
break;
}
Pemilihan pada
statemen switch ditentukan oleh
nilai ekspresi yang ditempatkan di dalam kurung, yang ada setelah katakunci switch. Pada kasus ini, ekspresi
merupakan sebuah variabel cuci yang perlu dideklarasikan sebagai tipe char, byte, short, atau int. Anda mendefinisikan opsi-opsi switch dengan satu atau lebih kasus,
menggunakan katakunci case. Umumnya,
tiap kasus memuat katakunci case
yang diikuti dengan sebuah nilai konstan yang merupakan nilai penentu kasus,
yang diikuti dengan simbol titik-dua. Statemen-statemen akan dieksekusi ketika
kasus tertentu dipilih berdasarkan nilai ekspresi. Pada contoh ini, Anda
memiliki tiga kasus, ditambah dengan kasus spesial dengan label default. Kasus spesial ini dipilih jika
nilai dari ekspresi switch (pada
kasus ini, cuci) tidak cocok dengan
nilai-nilai konstan kasus.
Ketika kasus
tertentu dipilih, statemen-statemen yang ada setelah label kasus akan
dieksekusi. Jadi, jika cuci bernilai
2, maka statemen-statemen yang ada setelah case
2 akan dieksekusi: Pada kasus ini, statemen-statemen tersebut adalah:
System.out.println(“Linen
dipilih”);
break;
Ketika statemen break dieksekusi, hal itu menyebabkan
eksekusi berlanjut ke statemen yang ada setelah kurung kurawal penutup switch, }. Statemen break tidak harus menjadi statemen
terakhir untuk tiap kasus, tetapi jika Anda tidak menempatkan statemen break di akhir statemen-statemen pada
sebuah kasus, maka statemen-statemen yang ada pada kasus berikutnya akan
dieksekusi pula. Statemen break pada
kasus default sebenarnya tidak diperlukan.
Anda bisa
menuliskan ulang statemen switch
sebelumnya dengan memanfaatkan sebuah variabel bertipe enumerasi sebagai
ekspresi pengendali statemen switch.
Dimisalkan Anda telah mendefinisikan tipe enumerasi PilihanCuci seperti ini:
enum PilihanCuci {katun,
linen, wol} // Mendefinisikan tipe
enumerasi
Anda sekarang
dapat menuliskan statemen switch
seperti ini:
PilihanCuci cuci =
PilihanCuci.linen; // Definisi awal
untuk variabel cuci
switch(cuci) {
case katun: //
cuci bernilai 1 untuk Katun
System.out.println(“Katun dipilih”);
break;
case linen: //
cuci bernilai 2 untuk Linen
System.out.println(“Linen dipilih”);
break;
case wol: //
cuci bernilai 3 untuk Wol
System.out.println(“Wol dipilih”);
break;
default: //
cuci tidak valid
System.out.println(“Error pemilihan”);
break;
}
Statemen switch dikendalikan oleh nilai dari
variabel cuci. Perhatikan bagaimana
Anda menggunakan konstanta enumerasi sebagai nilai kasus. Anda perlu
menuliskannya tanpa menyebutkan nama tipe enumerasi sebagai konstanta kasus.
Pada kasus ini, Anda menggunakan case
katun, bukan case PilihanCuci.katun.
Generalisasi Statemen switch
Logikal dari
statemen switch ditampilkan pada
diagram alir pada Gambar 3-4.
Gambar 3-4
Setiap nilai
kasus dibandingkan dengan nilai dari ekspresi. Jika salah satu cocok atau sama,
maka kode yang ada pada kasus itu akan dieksekusi, dan statemen break
menyebabkan aliran eksekusi melompat ke statemen pertama yang ada setelah switch. Jika Anda tidak mencantumkan
statemen break, maka logika program menjadi berbeda, seperti ditunjukkan pada
Gambar 3-5.
Sekarang ketika
sebuah nilai label kasus sama dengan ekspresi switch, kode untuk kasus itu akan dieksekusi, dan statemen-statemen
untuk semua kasus yang ada setelahnya juga akan dieksekusi, termasuk kasus
default.
Gambar 3-5
Anda dapat
mengeksekusi statemen-statemen yang sama untuk kasus-kasus berbeda, seperti
pada statemen switch berikut:
char yaTidak = ‘T’;
// logikal program lain…
switch(yaTidak) {
case ‘t’: case ‘T’:
System.out.println(“Tidak yang diseleksi”);
break;
case ‘y’: case ‘Y’:
System.out.println(“Ya yang diseleksi”);
break;
}
Di sini,
variabel yaTidak menerima sebuah
karakter dari keyboard. Anda menginginkan aksi berbeda tergantung dari apakah
user memasukkan ‘Y’ atau ‘T’, tetapi Anda menginginkan agar program dapat
menerima huruf besar maupun huruf kecil dari user. Statemen switch ini melakukannya dengan
menempatkan label-label kasus bersamaan. Perhatikan bahwa tidak ada kasus
default di sini. Jika yaTidak memuat sebuah karakter selain
yang diidentifikasi pada statemen-statemen kasus, statemen switch tidak
memiliki efek apapun. Pada prakteknya, Anda menambahkan kasus default pada
kasus ini untuk menampilkan sebuah pesan yang mengindikasikan bahwa nilai yaTidak tidak valid.
Tentu, Anda juga
dapat mengimplementasikan logika ini menggunakan statemen-statemen if:
if(yaTidak == ‘t’ || yaTidak
== ‘T’) {
System.out.println(“Tidak yang diseleksi”);
} else {
if(yaTidak == ‘y’ || yaTidak == ‘Y’) {
System.out.println(“Ya yang diseleksi”);
}
}
Latihan
|
Menggunakan
Statemen switch
|
Contoh ini
menggunakan sebuah statemen switch
yang dikendalikan oleh suatu variabel bertipe integer dan sebuah statemen switch yang dikendalikan oleh suatu
variabel bertipe enumerasi:
public class CobaSwitch {
// Mendefinisikan tipe enumerasi
enum PilihanCuci {katun, linen, wol,
sintetis}
public static void main(String[] args) {
// Variabel untuk medefinisikan pilihan
cuci
PilihanCuci cuci = PilihanCuci.katun;
// Variabel cuci menetapkan jenis pakaian
yang dicuci
// menggunakan nilai integer:
// 1:kemeja 2:sweater 3:kaus kaki
4:sepatu 5:celana
int pakaian = 3;
switch(pakaian) {
case 1:
System.out.println("Mencuci
kemeja.");
cuci = PilihanCuci.katun;
break;
case 2:
System.out.println("Mencuci
sweater.");
cuci = PilihanCuci.wol;
break;
case 3:
System.out.println("Mencuci
kaus-kaki.");
cuci = PilihanCuci.wol;
break;
case 4:
System.out.println("Mencuci
sepatu.");
cuci = PilihanCuci.linen;
break;
case 5:
System.out.println("Mencuci
celana.");
cuci = PilihanCuci.sintetis;
break;
default:
System.out.println("Mencuci tak
dikenal - default sintetis.");
cuci = PilihanCuci.sintetis;
break;
}
// Sekarang memilih suhu pencucian
System.out.println("Sedang mencuci
"+ cuci);
switch(cuci) {
case wol:
System.out.println("Suhu
pencucian 20 derajat Celcius.");
break;
case katun:
System.out.println("Suhu
pencucian 70 derajat Celcius.");
break;
case sintetis:
System.out.println("Suhu
pencucian 30 derajat Celcius.");
break;
case linen:
System.out.println("Suhu
pencucian 80 derajat Celcius.");
break;
}
}
}
Keluaran
program:
Mencuci kaus-kaki.
Sedang mencuci wol
Suhu pencucian 20 derajat
Celcius.
Penjelasan
Kode ini tampak
panjang, karena adanya sejumlah kasus pada dua statemen switch. Anda lebih dahulu mendefinisikan sebuah tipe enumerasi, PilihanCuci. Anda kemudian
mendefinisikan sebuah variabel bertipe enumerasi ini pada metode main() dengan statemen berikut:
PilihanCuci cuci =
PilihanCuci.katun;
Nilai awal untuk
cuci di sini dapat diubah menjadi
konstanta bertipe enumerasi PilihanCuci
yang lain. Selanjutnya, Anda mendefinisikan dan menginisialisasi sebuah
variabel yang mengidentifikasi tipe pakaian yang dicuci:
// Variabel cuci menetapkan
jenis pakaian yang dicuci
// menggunakan nilai
integer:
// 1:kemeja 2:sweater 3:kaus
kaki 4:sepatu 5:celana
int pakaian = 3;
Nilai awal untuk
variabel pakaian berkaitan dengan
kaus kaki. Anda menggunakan variabel pakaian
untuk mengendalikan statemen switch
dengan ekspresi pengendali pakaian.
Untuk setiap kasus pada switch ini,
Anda menampilkan apa yang sedang dicuci dan menetapkan nilai variabel cuci menjadi konstanta enumerasi
tertentu. Anda menempatkan sebuah kasus default
pada statemen switch ini karena
ekspresi pengendalinya adalah nilai numerik. Jika tidak ada kasus default dan
ekspresi pengendali swicth menghasilkan sebuah nilai yang tidak sama dengan
semua kasus yang ada, maka aliran eksekusi akan berlanjut ke statemen yang ada
setelah blok switch.
Setelah switch pertama, Anda menampilkan apa
yang sedang dicuci:
System.out.println("Sedang
mencuci "+ cuci);
Anda telah
melihat pada bab sebelumnya bahwa representasi string atas sebuah nilai yang
merupakan konstanta enumerasi adalah nama nilai seperti pada definisi tipe.
Terakhir, Anda
menggunakan variabel cuci sebagai
ekspresi untuk memilih sebuah kasus pada statemen switch berikutnya. Karena variabel bertipe enumerasi harus memiliki
konstanta enumerasi sebagai nilai, dan semua nilai yang mungkin
direpresentasikan oleh kasus-kasus pada switch,
maka Anda tidak memerlukan kasus default di sini.
Perhatikan bahwa
Anda bisa saja mendefinisikan nilai dari tiap pakaian sebagai nilai konstanta
seperti berikut:
final int KEMEJA = 1;
final int SWEATER = 2;
final int KAUSKAKI = 3;
final int SEPATU = 4;
final int CELANA = 5;
Nilai untuk
variabel pakaian kemudian dapat ditetapkan berikut:
int pakaian = KAUSKAKI;
Tentu, Anda bisa
juga menggunakan enumerasi untuk tipe pakaian,
tetapi hal itu biarlah menjadi tugas Anda.
Skop Variabel
Skop atas sebuah
variabel merupakan bagian program dimana nama variabel dapat diakses atau
dikenali. Setiap variabel yang telah dideklarasikan sejauh ini pada
contoh-contoh program telah didefinisikan di dalam sebuah metode main(). Setiap variabel yang
didefinisikan di dalam sebuah metode disebut dengan variabel lokal, karena
hanya dapat dieakses di dalam metode dimana variabel tersebut didefinisikan.
Lihat fragmen kode berikut, yang menunjukkan varibel-variabel yang
didefinisikan pada blok-blok bersarang:
{
int n = 1;
// Mengakses n dapat dilakukan di sini
// Mengakses m di sini mengakibatkan error
karena m belum ada
{
//
Mengakses n juga bisa dilakukan di sini
//
Mengakses m di sini masih menyebabkan error
int
m = 2; // Mendeklarasikan dan
mendefinisikan m
// Mengakses m dan n di sini bisa dilakukan, keduanya eksis
} // m lenyap di titik ini
//
Mengakses m akan menyebabkan error di sini
//
Mengakses n dapat juga dilakukan di sini
}
// n tidak bisa lagi diakses di sini
Sebuah variabel
tidak bisa diakses sebelum dideklarasikan; Anda hanya bisa mengaksesnya hanya
ketika variabel dideklarasikan. Variabel itu tetap dapat diakses sampai akhir
blok di mana ia didefinisikan, dan itu termasuk semua blok yang bersarang di
dalam blok pemuat variabel tersebut. Variabel n diciptakan pada statemen pertama pada blok terluar. Variabel itu
tetap ada dan bisa diakses di dalam blok yang bersarang di dalam blok terluar.
Variabel m hanya ada dan bisa
diakses di dalam blok bersarang karena di sana lah variabel itu dideklarasikan.
Setelah kurung-kurawal penutup di akhir blok bersarang, m tidak lagi ada dan tidak lagi bisa diakses. Variabel n masih tetap ada dan bisa diakses
sampai kurung-kurawal penutup dari blok terluar.
Jadi, aturan
yang menentukan aksesibilitas dari variabel lokal cukup sederhana. Variabel
lokal hanya dapat diakses dari titik pada program dimana variabel itu
dideklarasikan sampai akhir blok yang memuat pendeklarasian tersebut. Di akhir
blok dimana variabel lokal dideklarasikan, variabel itu tidak lagi bisa
diakses. Hal ini didemonstrasikan pada contoh berikut:
Latihan
|
Skop
Variabel
|
Berikut adalah
sebuah versi dari metode main() yang
mendemonstrasikan bagaimana skop variabel diterapkan dalam Java:
public class SkopVariabel {
public static void main(String[] args) {
int terluar = 1; // Exists throughout the
method
{
// Anda tidak bisa mengakses sebuah
variabel sebelum dideklarasikan
// Hapus ini akan terjadi error
// System.out.println("terdalam =
" + terdalam);
int terdalam = 2;
System.out.println("terdalam =
" + terdalam); // OK dilakukan
// dan terdalam masih dapat diakses di
sini
System.out.println("terluar =
" + terluar);
// Semua variabel yang didefinisikan
pada blok terluar masih
// dapat diakses di sini,
// jadi Anda tidak bisa melakukan
pendefinisian-ulang
// Hapus ini akan terjadi error
/ int terluar = 5;
}
// Semua variabel yang dideklarasikan
pada blok terdalam tidak lagi ada
// Jadi Anda tidak bisa mengaksesnya di
sini
// Hapus ini akan terjadi error
// System.out.println("terdalam =
" + terdalam);
// Variabel yang didefinisikan pada blok
terdalam
// tidak lagi ada, jadi Anda bisa
mendefiniskannya ulang
int terdalam = 3;
System.out.println("terdalam =
" + terdalam); // ... menampilkan nilainya
System.out.println("terluar = "
+ terluar); // terluar masih tetap ada
}
}
Keluaran
program:
terdalam = 2
terluar = 1
terdalam = 3
terluar = 1
Jika Anda
menghapus salah satu atau ketiga statemen yang diperingatkan, maka program
tidak akan bisa dikompilasi:
--------------------Configuration:
SkopVariabel - JDK version 1.8.0_131 <Default>
SkopVariabel.java:8: error:
cannot find symbol
System.out.println("terdalam =
" + terdalam);
^
symbol:
variable terdalam
location: class SkopVariabel
SkopVariabel.java:21: error:
variable terluar is already defined in method main(String[])
int terluar = 5;
^
SkopVariabel.java:28: error:
cannot find symbol
System.out.println("terdalam =
" + terdalam);
^
symbol:
variable terdalam
location: class SkopVariabel
3 errors
Penjelasan
Metode main() pada program ini memiliki satu
blok yang bersarang di dalam blok pemuat kode untuk metode ini. Variabel terluar didefinisikan tepat di awal
metode main(), jadi Anda dapat
mengaksesnya di mana saja di dalam metode main(),
termasuk di dalam blok bersarang. Anda tidak dibolehkan mendefinisikan ulang
sebuah variabel, jadi bila Anda mengaktifkan komentar yang mendefinisikan ulang
terluar di dalam blok bersarang, hal
itu akan menyebabkan error kompilasi.
Variabel terdalam didefinisikan di dalam blok
bersarang dengan nilai awal 2, dan Anda dapat mengaksesnya di mana saja dimulai
dari titik pendeklarasiannya sampai akhir blok bersarang. Setelah
kurung-kurawal penutup dari blok bersarang, variabel terdalam tidak lagi ada, jadi bila Anda mengaktifkan statemen yang
mengakses terdalam pada titik itu,
hal itu akan menyebabkan error kompilasi. Namun, karena variabel terdalam tidak lagi ada, Anda dapat
mendeklarasikan variabel lain dengan nama sama dengan nilai awal 3.
Perhatikan bahwa
ini hanya diperuntukkan untuk mendemonstrasikan bagaimana masa-hidup dari
variabel lokal diperlakukan. Anda tidak direkomendasikan mendefinisikan-ulang
variabel lokal yang telah habis masa-hidupnya, karena hal itu berpotensi memicu
kebingungan pembaca program.
Loop
Sebuah loop
dapat dipakai untuk mengeksekusi sebuah statemen atau blok statemen secara
berulang. Kebutuhan akan eksekusi berulang atas sebuah blok kode seringkali
dijumpai pada sebuah program. Perhatikan contoh program berikut:
public class CobaContoh1 {
public static void main(String[] args) {
int nilai = 1;
nilai *= 2;
System.out.println("Nilai sekarang
adalah "+nilai);
nilai *= 2;
System.out.println("Nilai sekarang
adalah "+nilai);
nilai *= 2;
System.out.println("Nilai sekarang
adalah "+nilai);
nilai *= 2;
System.out.println("Nilai sekarang
adalah "+nilai);
nilai *= 2;
System.out.println("Nilai sekarang
adalah "+nilai);
nilai *= 2;
System.out.println("Nilai sekarang
adalah "+nilai);
nilai *= 2;
System.out.println("Nilai sekarang
adalah "+nilai);
nilai *= 2;
System.out.println("Nilai sekarang
adalah "+nilai);
}
}
Pasangan-pasangan
statemen yang sama dimasukkan delapan kali. Ini merupakan cara melelahkan dalam
melakukan sesuatu. Jika program dipakai untuk menghitung tiap karyawan dengan
total 1000 karyawan, maka panjang program akan beratus-ratus halaman hanya
untuk melakukan pekerjaan yang sama. Anda bisa menuliskan program di atas untuk
melakukan pekerjaan sama seperti berikut:
public class CobaContoh1_1 {
public static void main(String[] args) {
int nilai = 1;
for (int i=0; i<8 ; i++) {
nilai *= 2;
System.out.println("Nilai
sekarang adalah "+nilai);
}
}
}
Ini merupakan
salah satu jenis loop, yang dikenal sebagai loop for. Statemen loop for
di baris keempat menyebabkan statemen-statemen pada blok loop for dieksekusi delapan kali. Banyak
eksekusi yang akan diulangi ditentukan oleh
kendali yang diapit di dalam kurung setelah katakunci for. Anda akan mempelajarinya sebentar
lagi. Tujuan utama dari loop for
adalah mengeksekusi sebuah blok statemen secara berulang, sesuai dengan yang
ditetapkan.
Secara umum,
sebuah loop memiliki dua bagian: tubuh
loop, yang merupakan sebuah statemen atau blok statemen yang mendefinisikan
kode yang akan dieksekusi secara berulang; mekanisme
kendali loop yang menentukan berapa kali eksekusi akan diulangi.
Varietas
Loop
Ada empat jenis
loop yang dapat digunakan:
1.
Loop for numeris:
for
(ekspresi_inisialisasi; kondisi_loop; ekspresi_inkremen) {
// statemen-statemen
}
Loop for numeris umumnya dinamakan sebagai
loop for saja. Tubuh loop ini adalah
blok statemen yang diapit oleh kurung-kurawal. Blok statemen ini bisa saja
berupa sebuah statemen, dimana pada kasus ini kurung-kurawal menjadi opsional.
Kode untuk mengendalikan loop for
ditempatkan di dalam kurung, yang ada setelah katakunci for. Seperti yang dapat Anda lihat, mekanisme kendali loop memiliki
tiga bagian, yang dipisahkan dengan titik-koma. Bagian pertama, ekspresi_inisialisasi, dieksekusi
sebelum loop diawali. Anda umumnya menggunakan ekspresi ini untuk
menginisialisasi sebuah pencacah untuk banyak iterasi loop, misalnya, i = 0.
Dengan sebuah loop dikendalikan oleh pencacah, yang dapat berupa variabel
integer atau variabel titik-mengambang, Anda dapat mencacah naik atau turuh
dengan inkremen atau dekremen sampai variabel mencapai batas yang
didefinisikan.
Eksekusi atas
loop ini berlanjut sepanjang kondisi yang Anda tetapkan pada bagian kedua dari
mekanisme kendali, kondisi_loop,
bernilai true. Ekspresi ini
diperiksa di awal dari tiap iterasi loop, dan sepanjang bernilai true, tubuh loop akan tetap dieksekusi.
Ketika kondisi_loop bernilai false, loop akan berakhir dan eksekusi
dilanjutkan ke statemen yang ada setelah blok loop. Misalnya, jika Anda
menggunakan i < 10 sebagai
ekspresi kondisi_loop, maka loop
akan tetap dieksekusi sepanjang variabel i memiliki nilai kurang dari 10.
Bagian ketiga dari mekanisme kendali, ekspresi_inkremen,
umumnya dipakai untuk menginkremen pencacah loop. Ini akan dieksekusi di akhir
dari tiap iterasi loop. Ekspresi ini dapat berupa i++, yang akan menginkremen
pencacah loop, i, sebesar 1. Tentu, Anda dapat menginkremen pencacah loop
dengan langkah lebih besar dari 1. Misalnya, Anda bisa saja menuliskan i += 2 sebagai
ekspresi_inkremen untuk menginkremen
pencacah loop sebesar 2, atau bahkan Anda bisa juga menggunakan, misalnya, i =
2*i + 1, sebagai ekspresi_inkremen.
2.
Loop for berbasis koleksi:
for
(tipe_data pengenal : ekspresi_iterasi) {
// statemen-statemen
}
Anda tidak akan
bisa memapahami kapabilitas loop ini sampai Anda mempelajari Collection, jadi Anda akan diberikan
penjelasan singkat saja tentang loop ini. Loop for ini memiliki dua elemen kendali yang dipisahkan oleh titik-dua
yang ada di dalam kurung setelah katakunci for.
Elemen pertama adalah pengenal
dengan tipe data yang Anda tetapkan, dan elemen kedua adalah sebuah ekspresi
yang menetapkan koleksi objek atau nilai yang ada pada koleksi, dan Anda dapat
mengakses item pada tubuh loop menggunakan pengenal.
Anda dapat menerapkan bentuk loop for
ini untuk array maupun untuk koleksi.
3.
Loop while:
while
(ekspresi) {
// statemen-statemen
}
Loop ini
dieksekusi sepanjang ekspresi logis yang diapit tanda-kurung bernilai true. Ketika ekspresi bernilai false,
maka loop loop akan berakhir dan eksekusi dilanjutkan pada statemen yang ada
setelah blok loop. Ekspresi ini diuji di awal loop, jadi jika awalnya bernilai false, maka tubuh loop tidak akan
dieksekusi sama sekali. Salah satu contoh dari kondisi loop while adalah yaTidak == ‘Y’ || yaTidak == ‘y’. Ekspresi ini akan bernilai true jika varaibel yaTidak memuat ‘y’ atau ‘Y’.
4.
Loop do while:
do {
//
statemen-statemen
} while (ekspresi);
Loop ini mirip
dengan loop while, kecuali bahwa
ekspresi pengendali loop diuji di akhir blok loop. Ini berarti bahwa tubuh loop
akan selalu dieksekusi sedikitnya satu kali eksekusi, bahkan jika ekspresi selalu bernilai false.
Logika dasar
dari keempat jenis loop ditunjukkan pada Gambar 3-6.
Gambar 3-6
Dua versi loop
memiliki mekanisme pengendali berbeda dalam mengendalikan banyak iterasi. Anda
dapat pula melihat cukup jelas bahwa perbedaan utama antara loop while dan loop do while adalah tempat di mana pengujian dilakukan.
Latihan
|
Loop
for Numerik
|
Akan diawali
dengan contoh yang sangat sederhana. Dimisalkan bahwa Anda ingin menghitung
penjumlahan atas integer-integer dari 1 sampai nilai tertentu yang diberikan.
Anda dapat melakukan ini menggunakan loop for
seperti pada contoh berikut:
public class LoopFor {
public static void main(String[] args) {
int limit = 20; // Penjumlahan dari 1
sampai nilai ini
// Penjumlahan akumulasi disimpan pada
variabel ini
int sum = 0;
// Loop dari 1 sampai nilai dari limit
for(int i = 1; i <= limit; i++) {
sum += i; // Menjumlahkan nilai
terkini dari i pada sum
}
System.out.println("sum = " +
sum);
}
}
Keluaran
program:
sum = 210
Anda bisa
mencoba nilai berbeda untuk limit
untuk mendapatkan hasil berbeda.
Penjelasan
Pencacah loop
adalah i, dan ia dideklarasikan dan diinisialisasi di dalam statemen loop for. Sintaksis untuk loop for ini ditunjukkan pada Gambar 3-7.
Seperti yang
Anda lihat, ada tiga elemen pengendali operasi loop for, dan ketiganya ada di dalam kurung yang ada setelah katakunci for. Secara berurutan, tujuan ketiga
elemen pengendali tersebut adalah untuk:
ð
Menetapkan
kondisi-kondisi awal loop, khususnya pencacah loop
ð
Menetapkan
kondisi untuk menentu kelanjutan eksekusi loop
ð
Menginkremen
pencacah loop
Ketiga elemen
pengendali loop dipisahkan oleh titik-koma. Elemen pengendali pertama
dieksekusi ketika loop pertama kali dieksekusi. Di sini, Anda mendeklarasikan
dan menginisialisasi pencacah loop, i. Karena pencacah loop dideklarasikan di
dalam loop, variabel i tidak dikenali di luar loop. Jika Anda mencoba
menampilkan nilai i di luar loop dengan statemen seperti:
System.out.println(“Nilai
akhir i = “ + i); // Tidak akan bisa
dikompilasi
Anda akan
menjumpai bahwa program tidak akan bisa dikompilasi.
Ketika tubuh
loop hanya memuat satu statemen, Anda dapat mengabaikan kurung-kurawal dan
menuliskan loop seperti ini:
for (int i = 1; i <=
limit; i++)
sum += i; //
Menambahkan nilai terkini dari i pada sum
Tetapi, Anda
direkomendasikan untuk tetap menggunakan kurung-kurawal untuk memperjelas di
mana tubuh loop berakhir.
Gambar 3-7
Jika Anda perlu
menginisialisasi dan/atau mendeklarasikan variabel-variabel lain untuk loop,
Anda dapat melakukannya di sini dengan memisahkan deklarasi-deklarasi dengan
koma. Misalnya, Anda dapat menuliskan:
for (int i = 1, j = 0; i
<= limit; i++) {
sum += i * j++; // Menambahkan nilai terkini dari i*j pada sum
}
Pada fragmen
kode ini, variabel j diinisialisasi. Perhatikan bahwa j akan diinkremen setelah
hasil dari i * j selesai dihitung. Anda dapat mendeklarasikan variabel-variabel
lain di situ.
Elemen
pengendali kedua pada sebuah loop for
adalah sebuah ekspresi logikal yang diperiksa di awal dari tiap iterasi loop.
Jika ekspresi bernilai true, maka
loop akan berlanjut, tubuh loop akan dieksekusi, dan ketika ekspresi bernilai false, tubuh loop tidak lagi
dieksekusi. Pada contoh program, loop berakhir ketika i lebih besar dari nilai
dari limit.
Elemen
pengendali ketiga pada sebuah loop for
umumnya menginkremen variabel loop, seperti yang telah Anda lihat pada contoh.
Anda dapat menempatkan beberapa ekspresi di sini. Misalnya, Anda dapat
menuliskan kembali fragmen kode sebelumnya dengan menambahkan j pada loop:
for (int i = 1, j = 0; i
<= limit; i++, j++) {
sum += i * j++; // Menambahkan nilai terkini dari i*j pada sum
}
Lagi, bisa
ditempatkan beberapa ekspresi di sini, meskipun tidak berkorelasi secara langsung
dengan kendali loop. Anda dapat menuliskan ulang loop semula untuk menjumlahkan
integer-integer sehingga penjumlahan terjadi pada elemen kendali loop:
for (int i = 1; i <=
limit; sum += i, i++) {
;
}
Sekarang,
statemen loop kosong, jadi Anda hanya perlu titik-koma untuk menghentikannya.
Versi kode ini memang tidak mudah untuk dipahami pembaca program dan ada
bahayanya bila menuliskan loop dengan cara ini. Jika Anda ingin membalikkan
urutan penjumlahan pada sum dan
penginkremenan i sebagai berikut:
for (int i = 1; i <=
limit; i++, sum += i) { // Salah!!
;
}
maka Anda akan
mendapatkan jawaban yang salah. Ini karena ekspresi i++ akan dieksekusi sebelum
sum += j dieksekusi. Jadi nilai
salah dari i yang digunakan.
Anda dapat
mengabaikan satu atau semua elemen yang mengendalikan loop for, tetapi Anda perlu mencantumkan titik-koma. Adalah tugas Anda
untuk memastikan bahwa loop melakukan apa yang Anda minta. Anda bisa menuliskan
ulang loop pada program menjadi berikut:
for (int i = 1; i <=
limit;) {
sum += i++; //
Menambahkan nilai terkini dari i pada sum
}
Mencacah Menggunakan Nilai-Nilai
Titik-Mengambang
Anda bisa
menggunakan variabel titik-mengambang sebagai pencacah loop jika diperlukan.
Ini diperlukan ketika Anda sedang menghitung nilai dari sebuah fungsi untuk
suatu rentang nilai pecahan. Dimisalkan bahwa Anda ingin menghitung luas
lingkaran dengan nilai radius dari 1 sampai 2 dengan langkah 0.2. Anda dapat
menuliskannya seperti ini:
for (double radius = 1.0;
radius <= 2.0; radius += 0.2) {
System.out.println(“radius = “ + radius + “
luas = “ + Math.PI*radius*radius);
}
Ini akan
menghasilkan keluaran:
radius = 1.0 luas =
3.141592653589793
radius = 1.2 luas =
4.523893421169302
radius = 1.4 luas = 6.157521601035994
radius = 1.5999999999999999
luas = 8.04247719318987
radius = 1.7999999999999998
luas = 10.178760197630927
radius = 1.9999999999999998
luas = 12.566370614359169
Luas telah
dihitung menggunakan formula ( dengan nilai standar PI yang didefinisikan pada kelas Math). Meskipun Anda bermaksud untuk mencacah nilai radius dari 1.0 sampai 2.0 dengan
inkremen 0.2, tetapi tampaknya hal itu tidak berhasil dilakukan. Nilai radius tidak pernah sampai persis 2.0
atau nilai-nilai lainnya karena 0.2 tidak dapat secara eksak direpresentasikan
sebagai sebuah nilai titik-mengambang biner. Jika Anda meragukannya, bersiaplah
untuk menangani sebuah loop tak-hingg bila mengubah loop tersebut menjadi:
for (double radius = 1.0;
radius != 2.0; radius += 0.2) {
System.out.println(“radius = “ + radius + “
luas = “ + Math.PI*radius*radius);
}
Jika nilai
radius mencapai 2.0, kondisi radius != 2.0 akan tetap bernilai false dan loop
akan berakhir, tetapi sayangnya hal itu tidak terjadi. Nilai terakhirnya sebelum
2 adalah nilai pendekatan, 1.999999… dan nilai berikutnya adalah 2.199999… jadi
ia tidak akan mencapai nilai 2.0.
Gambar 3-8
Latihan
|
Loop
for Berbasis Koleksi
|
Salah satu
terapan dari loop for berbasis
koleksi adalah untuk menjejak enumerasi. Di sini, akan ditunjukkan bagaimana
loop for berbasis koleksi dipakai
untuk menjejak semua nilai pada sebuah enumerasi.
public class LoopForKoleksi
{
enum Musim {semi, panas,
gugur, dingin} // Definisi tipe enumerasi
public static void main(String[] args) {
for(Musim musim : Musim.values()) {
System.out.println("Musim
sekarang adalah " + musim);
}
}
}
Keluaran
program:
Musim sekarang adalah semi
Musim sekarang adalah panas
Musim sekarang adalah gugur
Musim sekarang adalah dingin
Penjelasan
Gambar 3-8
menjelaskan bagaimana loop for
berbasis koleksi dipakai. Variabel musim
bertipe Musim yang ditempatkan
sebagai ekspresi pengendali pertama pada loop for akan ditugasi nilai konstanta
enumerasi berbeda pada tiap iterasi loop. Ekspresi kendali kedua, setelah
titik-dua, mengidentifikasi koleksi yang merupakan sumber nilai untuk variabel
yang dideklarasikan pada ekspresi pengendali pertama. Pada kasus ini, sumber
nilai adalah sebuah enumerasi, tetapi umumnya, ada sejumlah koleksi yang dapat
Anda gunakan, seperti array dan objek koleksi pada kelas Collection. Pada bab mendatang, Anda akan belajar tentang array
dimana kedua jenis loop for dapat
dipakai.
Pada contoh ini,
enumerasi mendefinisikan empat nilai: semi,
panas, gugur, dan dingin, jadi
variabel musim akan ditugasi tiap
nilai ini secara bergiliran, seperti yang ditunjukkan pada keluaran program.
Latihan
|
Loop
while
|
Anda dapat
menuliskan program untuk menjumlahkan integer-integer kembali menggunakan loop while, yang akan menunjukkan pada Anda
bagaimana mekanisme loop ini berbeda dari loop for:
public class LoopWhile {
public static void main(String[] args) {
int limit = 20; // Menjumlahkan dari 1 sampai nilai ini
int sum = 0; // Mengakumulasikan penjumlahan pada variabel ini
int i = 1; // Pencacah loop
// Loop dari 1 sampai nilai limit,
// Menambahkan 1 pada tiap siklus
while(i <= limit) {
sum += i++; // Menambahkan nilai
terkini dari 1 pada sum
}
System.out.println("sum = " +
sum);
}
}
Keluaran program
sama dengan contoh sebelumnya.
Penjelasan
Loop while dikendalikan secara total oleh
ekspresi logikal yang ada di dalam kurung setelah katakunci while. Loop ini berlanjut dieksekusi
sepanjang ekspresi ini memiliki nilai true.
Anda perlu memastikan bahwa statemen-statemen di dalam loop pada akhirnya akan
menyebabkan ekspresi logikal ini bernilai false.
Jika tidak, Anda akan memiliki sebuah loop yang akan terus dieksekusi secara
tak berhingga.
Bagaimana loop
berhenti dieksekusi cukup jelas pada contoh ini. Anda memiliki pencacah
sederhana seperti sebelumnya, dan Anda menginkremen i pada statemen loop yang
mengakumulasi penjumlahan integer. Cepat atau lambat, i akan melebihi limit, dan loop while akan berhenti dieksekusi.
Latihan
|
Loop
do while
|
Seperti yang
telah disebutkan, loop do while bekerja sama seperti loop while, kecuali fakta bahwa kondisi
pengujian diperiksa di akhir loop. Anda dapat menuliskan-ulang program
penjumlah integer dengan jenis loop ini:
public class LoopDoWhile {
public static void main(String[] args) {
int limit = 20; // Menjumlahkan dari 1 sampai nilai ini
int sum = 0; // Mengakumulasikan penjumlahan pada variabel ini
int i = 1; // Pencacah loop
// Loop dari 1 sampai nilai limit,
// Menambahkan 1 pada tiap siklus
do {
sum += i++; // Menambahkan nilai
terkini dari 1 pada sum
} while(i <= limit);
System.out.println("sum = " +
sum);
}
}
Keluaran program
sama dengan contoh sebelumnya.
Penjelasan
Statemen-statemen
di dalam loop selalu dieksekusi sedikitnya sekali karena kondisi yang
menentukan apakah loop akan berlanjut diuji di akhir dari tiap iterasi. Di
dalam loop, Anda menambahkan nilai i pada sum,
dan kemudian menginkremennya. Ketika i melebihi nilai dari limit, loop akan berhenti, dimana pada titik itu sum akan memuat penjumlahan atas semua
integer dari 1 sampai limit.
Statemen loop di
sini memiliki kurung-kurawal yang mengapit blok kode yang berada di dalam loop.
Anda dapat menuliskan ulang loop sehingga satu-satunya statemen berada di dalam
loop, tanpa adanya kurung-kurawal. Sebagai contoh:
do
sum += i++; // Menambahkan nilai terkini
dari 1 pada sum
while(i <= limit);
Tentu, Anda
tetap direkomendasikan untuk selalu menggunakan kurung-kurawal untuk mengapit
blok kode yang ada di dalam loop, meski jika blok kode tersebut hanyalah satu
buah statemen.
Loop
Bersarang
Anda dapat
menyarangkan loop di dalam loop lain. Lihat contoh berikut:
Latihan
|
Menghitung
Faktorial
|
Contoh ini akan
menghitung faktorial dari tiap integer dari 1 sampai batas tertentu. Ketikkan
kode berikut:
public class Faktorial {
public static void main(String[] args) {
long limit = 20L; // Menghitung faktorial integer sampai nilai ini
long faktorial = 1L; // Hasilnya disimpan pada variabel ini
// Loop dari 1 sampai limit
for (long i = 1L; i <= limit; i++) {
faktorial = 1L; // Menginisialisasi
faktorial
for (long faktor = 2; faktor <= i;
faktor++) {
faktorial *= faktor;
}
System.out.println(i + "! adalah
" + faktorial);
}
}
}
Keluaran
program:
1! adalah 1
2! adalah 2
3! adalah 6
4! adalah 24
5! adalah 120
6! adalah 720
7! adalah 5040
8! adalah 40320
9! adalah 362880
10! adalah 3628800
11! adalah 39916800
12! adalah 479001600
13! adalah 6227020800
14! adalah 87178291200
15! adalah 1307674368000
16! adalah 20922789888000
17! adalah 355687428096000
18! adalah 6402373705728000
19! adalah
121645100408832000
20! adalah
2432902008176640000
Penjelasan
Semua variabel
yang digunakan pada contoh ini bertipe long.
Nilai-nilai faktorial membesar sangat cepat sehingga penggunaan tipe long sangat tepat untuk menampung
nilai-nilai faktorial yang lebih besari daripada bila Anda menggunakan tipe int. Anda sebenarnya masih bisa
mendeklarasikan faktor dan i sebagai
tipe int tanpa perlu membatasi
ukuran nilai faktorial yang dapat dihasilkan program, tetapi kompilator
kemudian perlu menyisipkan konversi tipe untuk membuat nilai int menjadi tipe long.
Loop terluar,
yang dikendalikan i, menjejak semua integer dari 1 sampai nilai dari limit. Pada tiap iterasi dari loop
terluar, variabel faktorial diinisialisasi
dengan 1, dan loop bersarang menghitung faktorial atas nilai terkini dari i
menggunakan faktor sebagai pencacah
pengendali yang dijalankan dari 2 sampai nilai terkini dari i. Hasil dari faktorial kemudian ditampilkan sebelum
menjejak iterasi selanjutnya dari loop terluar.
Meskipun Anda
memiliki sebuah loop for bersarang di dalam loop for lain di sini, seperti
dijelaskan sebelumnya, Anda dapat menyarangkan sembarang jenis loop di dalam
sembarang jenis loop lainnya. Anda dapat menuliskan loop bersarang sebagai
berikut:
// Loop dari 1 sampai limit
for (long i = 1L; i <=
limit; i++) {
faktorial = 1L; // Menginisialisasi
faktorial
long faktor = 2L;
while (faktor <= i) {
faktorial *= faktor++;
}
System.out.println(i + "! adalah "
+ faktorial);
}
Sekarang, Anda
memiliki sebuah loop while yang
bersarang di dalam sebuah loop for.
Keluaran program sama seperti sebelumnya.
Statemen
continue
Ada beberapa
situasi dimana Anda ingin melompati semua atau sebagian dari iterasi loop.
Dimisalkan bahwa Anda ingin menjumlahkan nilai-nilai dari integer 1 sampai
batas tertentu, dimana Anda tidak ingin melibatkan integer-integer yang
merupakan kelipatan tiga. Anda dapat melakukan ini menggunakan if dan continue:
for (int i = 1; i <= limit;
i++)
if(i % 3 == 0) {
continue; //
Melompati sisa iterasi
}
sum += i; //
Menjumlahkan nilai terkini dari i pada sum
}
Statemen
continue dieksekusi pada contoh ini ketika i merupakan kelipatan 3, yang
menyebabkan sisa dari iterasi loop terkini dilompati. Eksekusi program
dilanjutkan ke iterasi selanjutnya jika ada, jika tidak, dilanjutkan ke
statemen pertama yang ada setelah blok loop. Statemen continue dapat ditempatkan di mana saja di dalam blok loop. Anda
bahkan bisa memiliki lebih dari satu continue
pada sebuah loop.
Statemen continue Berlabel
Ketika Anda
memiliki loop bersarang, ada bentuk spesial dari statemen continue yang memampukan Anda untuk menghentikan eksekusi atas loop
terdalam (loop bersarang), bukan hanya menghentikan eksekusi atas iterasi
terkini dari loop bersarang. Eksekusi program kemudian dilanjutkan ke iterasi
selanjutnya dari loop terluar. Ini dinamakan dengan statemen continue berlabel.
Untuk
menggunakan statemen continue
berlabel, Anda perlu mengidentifikasi statemen loop sebagai loop terluar
pengapit menggunakan label statemen.
Label statemen adalah sebuah pengenal yang dipakai untuk mengakses statemen
tertent. Ketika Anda mengakses statemen tertentu, Anda menuliskan label
statemen di awal statemen tersebut, yang dipisahkan dengan titik-dua. Lihat
contoh berikut:
Latihan
|
Statemen
continue Berlabel
|
Anda dapat
menambahkan sebuah statemen continue
berlabel untuk mengabaikan perhitungan faktorial atas nilai-nilai ganjil yang
lebih besar dari 10.
public class
ContinueBerlabel {
public static void main(String[] args) {
long limit = 20L; // Menghitung faktorial integer sampai nilai ini
long faktorial = 1L; // Hasilnya disimpan pada variabel ini
LoopTerluar:
// Loop dari 1 sampai limit
for (long i = 1L; i <= limit; i++) {
faktorial = 1L; // Menginisialisasi
faktorial
for (long j = 2; j <= i; j++) {
if(i
> 10L && i % 2L == 1L) {
continue LoopTerluar; // Pindah
ke loop terluar
}
faktorial *= j;
}
System.out.println(i + "! adalah
" + faktorial);
}
}
}
Keluaran
program:
1! adalah 1
2! adalah 2
3! adalah 6
4! adalah 24
5! adalah 120
6! adalah 720
7! adalah 5040
8! adalah 40320
9! adalah 362880
10! adalah 3628800
12! adalah 479001600
14! adalah 87178291200
16! adalah 20922789888000
18! adalah 6402373705728000
20! adalah
2432902008176640000
Penjelasan
Loop terluar
memiliki label LoopTerluar. Pada
loop bersarang, ketika kondisi pada statemen if bernilai true,
statemen continue berlabel akan
dieksekusi yang menyebabkan kendali program berpindah ke awal dari iterasi
berikutnya dari loop terluar. Kondisi pada statemen if menyebabkan perhitungan atas faktorial dilompati untuk
nilai-nilai ganjil yang lebih besar dari 10.
Menggunakan
Statemen break Pada Loop
Anda telah
melihat bagaimana menggunakan statemen break
pada sebuah blok switch. Efeknya
adalah untuk keluar blok switch dan
melanjutkan eksekusi ke statemen pertama yang ada setelah blok switch. Anda dapat pula menggunakan
statemen break untuk keluar dari sebuah loop. Ketika break dieksekusi di dalam
sebuah loop, loop tersebut akan berhenti dieksekusi, dan kendali program akan
berlanjut ke statemen pertama yang ada setelah loop. Untuk
mendemonstrasikannya, Anda akan menuliskan sebuah program untuk mencari
nilai-nilai prima.
Latihan
|
Menghitung
Prima I
|
Kode berikut
sedikit lebih panjang dari contoh sebelumnya. Program ini akan menemukan semua
bilangan prima dari 2 sampai 50:
public class Prima {
public static void main(String[] args) {
int nNilai = 50; // Nila maksimum yang
diperiksa
boolean apaPrima = true; // Bernilai true
jika ditemukan prima
// Memeriksa semua nilai dari 2 sampai
nNilai
for(int i = 2; i <= nNilai; i++) {
apaPrima=true; // Asumsi i terkini
adalah prima
// Coba membagi semua integer dari 2
sampai i-1
for(int j = 2; j < i; j++) {
if(i % j == 0) { // Bernilai true
jika dibagi habis oleh j
apaPrima = false; // Jika sampai
di sini, berarti pembagian habis
break; // keluar loop
}
}
// Anda dapat sampai di sini melalui
break,
// atau setelah menuntaskan loop
if(apaPrima) // jadi, apa prima?
System.out.println(i); // ya,
tampilkan keluaran
}
}
}
Keluaran
programm:
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
Penjelasan
Ada banyak cara
efisien untuk menghitung bilangan prima, tetapi program ini cukup untuk
mendemonstrasikan statemen break.
Langkah pertama pada main() adalah
mendeklarasikan dua variabel:
int nNilai = 50; // Nila
maksimum yang diperiksa
boolean apaPrima = true; //
Bernilai true jika ditemukan prima
Variabel pertama
adalah batas atas untuk integer-integer yang akan diperiksa keprimaannya.
Variabel apaPrima akan dipakai untuk
merekam apakah nilai tertentu prima atau bukan.
Ide dasar dari
program adalah menjejak integer dari 2 sampai nilai dari nNilai dan memeriksa
setiap integer tersebut untuk melihat apakah integer tersebut habis dibagi oleh
integer-integer lain selain dirinya sendiri. Loop-loop berikut melakukannya:
// Memeriksa semua nilai
dari 2 sampai nNilai
for(int i = 2; i <=
nNilai; i++) {
apaPrima=true; // Asumsi i terkini adalah
prima
// Coba membagi semua integer dari 2 sampai
i-1
for(int j = 2; j < i; j++) {
if(i
% j == 0) { // Bernilai true jika dibagi habis oleh j
apaPrima
= false; // Jika sampai di sini, berarti pembagian habis
break; // keluar loop
}
}
Loop terluar
diindeks oleh i dan menjejak semua nilai yang perlu diperiksa keprimaannya.
Loop terdalam diindeks oleh j yang merupakan nilai pembagi. Ini menentukan
keprimaan atas setiap integer yang nilainya kurang dari nilai yang sedang
diuji.
Pemeriksaan
dilakukan pada statemen if di dalam
loop terdalam. Jika i habis dibagi oleh j tanpa sis, berarti i%j menghasilkan
0, jadi apaPrima akan bernilai false. Pada kasus ini, statemen break
akan dieksekusi untuk keluar dari loop terdalam. Tidak ada gunanya lagi bila
melanjutkan eksekusi jika nilai yang sedang diuji bukanlah bilangan prima.
Statemen
selanjutnya yang akan dieksekusi adalah statemen if yang ada setelah kurung-kurawal penutup dari blok loop terdalam.
Eksekusi program dapat mencapai titik ini melalui cara keluar normal dari loop
yang terjadi ketika nilai yang diuji adalah bilangan prima. Variabel apaPrima menyelesaikan masalah ini dan
jika ia bernilai true, maka Anda
memiliki nilai prima yang akan ditampilkan.
Latihan
|
Menghitung
Prima II
|
Cobalah
melakukan perubahan-perubahan ini pada kode pada kelas Prima:
public class Prima2 {
public static void main(String[] args) {
int nNilai = 50; // Nila maksimum yang
diperiksa
// Memeriksa semua nilai dari 2 sampai
nNilai
LoopTerluar:
for(int i = 2; i <= nNilai; i++) {
// Coba membagi semua integer dari 2
sampai i-1
for(int j = 2; j < i; j++) {
if(i % j == 0) { // Bernilai true
jika dibagi habis oleh j
continue LoopTerluar; // keluar
loop
}
}
// Anda dapat sampai di sini hanya
ketika memiliki sebuah bilangan prima
System.out.println(i); // ya,
tampilkan keluaran
}
}
}
Jika Anda
melakukannya dengan benar, Anda akan mendapatkan keluaran yang sama seperti
contoh sebelumnya.
Penjelasan
Anda tidak lagi
memerlukan variabel apaPrima untuk mengindikasikan apakah Anda memiliki nilai
prima atau tidak, karena statemen keluaran dapat dicapai hanya melalui cara
keluar normal dari loop terdalam. Ketika ini terjadi, maka Anda memiliki
bilangan prima. Jika Anda mendapatkan bahwa i dapat dibagi habis oleh j pada
loop terdalam, maka ini mengimplikasikan bahwa nilai terkini dari i bukanlah
bilangan prima, jadi statemen continue
berlabel mengalihkan eksekusi ke iterasi selanjutnya pada loop terluar.
Keluar dari Loop Tak-Tentu
Anda bisa jadi
memerlukan sebuah loop yang banyak iterasinya tidak bisa Anda ketahui
sebelumnya. Ini bisa terjadi ketika Anda memproses item-item data eksternal
yang dibaca dari keyboard, misalnya, dan Anda tidak mengetahui berapa banya
item data tersebut. Anda dapat menggunakan sebuah loop while, dengan kondisi loop menentukan kapan loop akan berhenti,
tetapi ada kalanya hal itu lebih mudah dilakukan menggunakan sebuah loop
tak-tentu dan menggunakan statemen break
di dalam tubuh loop untuk mengakhiri loop. Loop tak-tentu adalah sebuah loop
dimana mekanisme kendalinya diciptakan sehingga loop dapat tetap dieksekusi
dengan banyak iterasi tak ditentukan. Pada kasus ini, mekanisme untuk
mengakhiri loop harus ditempatkan di dalam tubuh loop.
Latihan
|
Menghitung
Prima III
|
Dimisalkan bahwa
Anda menginginkan agar program Prima membangkitkan sejumlah bilangan prima,
bukan memeriksa nilai integer tertentu. Pada kasus ini, Anda tidak mengetahui
berapa banyak nilai yang perlu diperiksa untuk menghasilkan sejumlah bilangan
prima yang diperlukan. Inilah sebuah kasus dimana sebuah loop tak-tentu
berguna. Anda dapat melakukannya sebagai berikut:
public class Prima3 {
public static void main(String[] args) {
int nPrima = 50; // Banyak prima yang
dihasilkan
// Memeriksa semua nilai dari 2 sampai
nNilai
LoopTerluar:
for(int i = 2; ; i++) { // Loop ini
berjalan selamanya
// Coba membagi semua integer dari 2
sampai i-1
for(int j = 2; j < i; j++) {
if(i % j == 0) { // Bernilai true
jika dibagi habis oleh j
continue LoopTerluar; // keluar
loop
}
}
// Anda dapat sampai di sini hanya
ketika memiliki sebuah bilangan prima
System.out.println(i); // ya,
tampilkan keluaran
if(--nPrima == 0) { // Mendekremen
cacah prima
break;
}
}
}
}
Program ini akan
menampilkan 50 bilangan pertama.
Penjelasan
Program ini
sangat mirip dengan versi sebelumnya. Perbedaan utamanya adalah bahwa nPrima memuat banyak prima yang
diperlukan, jadi program akan menghasilkan 50 bilangan prima pertama, bukan
mencari bilangan prima antara 2 sampai 50, dan loop terluar for, yang dikendalikan i, memiliki
kondisi loop yang diabaikan, jadi loop tidak memiliki mekanisme langsung untuk
mengakhiri loop. Loop harus dihentikan oleh kode di dalam loop; jika tidak,
loop akan dieksekusi selamanya.
Di sini
penghentian eksekusi atas loop terluar dikendalikan oleh statemen if yang ada setelah statemen keluaran.
Ketika sebuah bilangan prima dihasilkan, nilai tersebut akan ditampilkan, dan
nilai dari nPrima didekremen pada
statemen if berikut:
if(--nPrima == 0) { //
Mendekremen cacah prima
break;
}
Statemen break akan dieksekusi ketika nPrima didekremen menjadi nol, dan ini
akan menghentikan eksekusi loop terluar.
Statemen break Berlabel
Java juga
menyediakan statemen break berlabel
bagi Anda. Ini memampukan Anda untuk melompat ke statemen yang ada setelah
akhir dari blok penutup atau akhir dari loop. Label mengawali kurung-kurawal
pembuka dari blok yang diidentifikasinya. Gambar 3-9 mengilustrasikan bagaimana
statemen break berlabel bekerja.
Statemen break berlabel dapat
dipakai untuk keluar dari blok atau loop yang memiliki label, tanpa memandang
berapa banyak level blok-blok bersarang.
Gambar 3-9
Lihat bagaimana
Anda bisa mengubah contoh sebelumnya dengan menggunakan sebuah statemen break berlabel:
public class Prima4 {
public static void main(String[] args) {
int nPrima = 50; // Banyak prima yang
dihasilkan
// Memeriksa semua nilai dari 2 sampai
nNilai
LoopTerluar:
for(int i = 2; ; i++) { // Loop ini
berjalan selamanya
// Coba membagi semua integer dari 2
sampai i-1
for(int j = 2; j < i; j++) {
if(i % j == 0) { // Bernilai true
jika dibagi habis oleh j
continue LoopTerluar; // keluar
loop
}
}
// Anda dapat sampai di sini hanya
ketika memiliki sebuah bilangan prima
System.out.println(i); // ya,
tampilkan keluaran
if(--nPrima == 0) { // Mendekremen cacah
prima
break LoopTerluar;
}
}
// Keluar LoopTerluar
}
}
Program ini
bekerja sama persis seperti contoh sebelumnya. Statemen break berlabel
mengakhiri operasi loop yang diawali dengan label LoopTerluar, dan sangat efektif untuk keluar ke titik yang
diindikasikan oleh komentar.