Mengenal Bahasa Pemrograman Java

Sejarah Java Java dipelopori oleh James Gosling, Patrick Naughton, Chris Warth, Ed Frank, dan Mike Sheridan dari Sun Microsystems, Inc pada tahun 1991. Mereka membutuhkan kurang lebih 18 bulan untuk membuat versi pertamanya. Bahasa ini pada awalnya disebut “Oak” tapi kemudian diubah menjadi “Java” pada tahun 1995 karena nama Oak telah dijadikan hak cipta dan digunakan sebagai bahasa pemrograman lainnya. Antara pembuatan Oak pada musim gugur 1992 hingga diumumkan ke publik pada musim semi 1995, banyak orang yang terlibat dalam desain dan evolusi bahasa ini. Bill Joy, Arthur van Hoff, Jonathan Payne, Frank Yellin, dan Tim Lindholm merupakan kontributor kunci yang mematangkan prototipe aslinya. Java Modern Java telah digunakan dalam banyak hal dan telah membuktikan keberadaannya pada abad ke 21. Saat ini, Java digunakan bermacam jenis aplikasi seperti aplikasi embedded, aplikasi keuangan, desktop, simulasi pesawat, pemrosesan citra, game, aplikasi perusahaan terdistribusi yang disebut J2EE dan masih banyak lagi. Java Virtual Machine (JVM) Java Virtual Machine merupakan aplikasi sederhana yang ditulis dalam bahasa C untuk mengeksi program yang ditulis dalam bahasa Java. Pada saat kompilasi (perubahan dari bahasa tingkat tinggi ke bahasa lebih rendah), program tersebut diubah menjadi KODE BYTE. Kemudian pada saat eksekusi, JVM membaca kode byte tersebu dan mengubahnya menjadi bahasa mesin yang dimengerti oleh sistem operasi tempat program tersebut dijalankan. Karena JVM sangat bergantung pada platformnya (bahasa mesin merupakan bahasa level rendah yang hanya dimengerti oleh suatu mesin tertentu, misalnya Intel, tapi tidak dapat dimengerti oleh mesin lain, seperti Macintosh), byte code ini dapat dibuat untuk terbebas dari kungkungan platform tertentu. Code byte yang dihasilkan dalam proses kompilasi bahasa Java akan selalu sama untuk setiap sistem operasi atau jenis mesinnya, tetapi JVM akan mengubah kode byte tersebut menjadi bahasa mesin tujuannya. Just In Time Compiler (JIT) Meskipun Java didesain untuk diinterpretasi, secara teknis tidak ada yang menghalangi Java untuk dikompilasi menjadi bahasa mesin seperti bahasa-bahasa pemrograman lainnya. Sun menyediakan kompiler Just In Time Compiler (JIT) untuk mengkompilasi kode byte itu menjadi bahasa mesinnya pada saat yang bersamaan dengan ekseku

Kelebihan Java
Bahasa pemrograman lain yang telah ada sebelum Java lahir sudah merupakan bahasa yang baik dan mudah dipelajasi oleh programmer profesional. Akan tetapi para programmer ini menginginkan sesuatu yang baru yang memiliki banyak hal yang menyelesaikan masalah

mereka. Utamanya adalah keamanan kode mereka. Hal ini melahirkan pikiran yang revolusioner untuk menemukan bahasa pemrograman lain yang disebut Java. Tidak hanya keamanan tapi juga beberapa hal yang sering disebut sebagai Java-Buzzwords. Kata-kata ini menjelaskan berbagai fitur tambahan dan beberapa hal yang membuat Java demikian sukses dan diterima oleh dunia perangkat lunak. Berikut ini adalah penjelasan serta keuntungan dari kata-kata tersebut. Sederhana dan Berorientasi Objek Seperti diuraikan sebelumnya, Java lahir dari suatu pemikiran mendalam akan bahasa pemrograman yang ada pada saat itu, seperti C dan C++. Hal ini akan memudahkan programmer profesional untuk dapat mengerti lebih jelas tentang Java, fungsionalitas, dan lain sebagainya apabila ia memiliki pengetahuan dasar tentang C++ dan konsep pemrograman berorientasi objek. Tujuannya agar konsep dasar dari teknologi Java dapat dimengerti dengan mudah, dan programmer dapat segera menghasilkan sesuatu sedini mungkin. Tidak hanya ini, penemu Java memastikan bahwa Java juga bermula dari bahasa pemrograman dasar yang sudah ada pada saat itu. Kemudian mereka membuang berbagai fitur yang rumit dan membingungkan. Bahasa pemrograman Java didesain sejak awal untuk menjadi bahasa yang berorientasi objek. Setelah kira-kira 30 tahun, akhirnya teknologi objek menjadi kenyataan dan diterima oleh sebagian besar komunitas pemrograman. Konsep berorientasi objek memungkinkan pembuatan software yang kompleks, berbasis network, sehingga dapat disimpulkan bahwa teknologi Java menghasilkan platform pembuatan perangkat lunak yang baik dan efisien serta berorientasi objek. Keuntungan yang Anda dapat dari Java • Mulai dengan cepat: Java merupakan bahasa pemrograman berorientasi objek, mudah dipelajari, terutama untuk programmer yang sudah menguasai C atau C++ • Tulis lebih sedikit program: Jumlah kelas, jumlah metode, dll, menunjukkan bahwa program yang ditulis dalam bahasa pemrograman Java memiliki jumlah 4 kali lipat lebih kecil dari program sama yang ditulis dalam bahasa C++ • Tulis program lebih baik: Bahasa pemrograman Java menganjurkan praktek membuat program yang baik, dan automatic garbage collection membantu Anda untuk menghindari kebocoran memori. Orientasi objeknya, arsitektur komponen JavaBeans, dan jangkauannya yanga luas, API yang mudah diperluas, memungkinkan Anda menggunakan kode yang ada. • Membuat program dengan lebih cepat: Bahasa pemrograman Java lebih mudah dari C++, pemrograman akan menjadi 2 kali lipat lebih cepat, dengan jumlah baris yang jauh lebih sedikit. • Menghindari kebergantungan pada platform tertentu: Anda dapat menjalankan program Anda pada banyak platform dengan TIDAK menggunakan library yang ditulis spesifik untuk platform tertentu. • Tulis sekali, jalankan di mana saja: Karena aplikasi yang ditulis dalam bahasa Java dikompilasi ke dalam kode byte yang bebas platform, aplikasi yang ditulis dapat jalan secara konsisten pada platform apa saja. • Distribusikan software Anda dengan mudah: Dengan Java Web Start, pengguna program Anda akan dapat menggunakan aplikasi Anda dengan mudah. Sistem pengecekan versi otomatis pada saat program dimulai menjamin pengguna Anda selalu menjalankan versi terkini. Apabila versi baru tersedia, Java Web Start akan melakukan instalasi secara otomatis.

Bab II - Instalasi Eclipse IDE
Eclipse merupakan komunitas open source yang bertujuan menghasilkan platform pemrograman terbuka. Eclipse terdiri dari framework yang dapat dikembangkan lebih lanjut, peralatan bantu untuk membuat dan memanage software sejak awal hingga diluncurkan. Platform Eclipse didukung oleh ekosistem besar yang terdiri dari vendor tekonologi, start-up inovatif, universitas, riset institusi serta individu. Banyak orang mengenal Eclipse sebagai IDE (integrated development environment) untuk bahasa Java, tapi Eclipse lebih dari sekedar IDE untuk Java. Komunitas Eclipse memiliki lebih dari 60 proyek open source. Proyek-proyek ini secara konsep terbagi menjadi 7 categori : 1. Enterprise Development 2. Embedded and Device Development 3. Rich Client Platform 4. Rich Internet Applications 5. Application Frameworks 6. Application Lifecycle Management (ALM) 7. Service Oriented Architecture (SOA) Secara umum Eclipse digunakan untuk membangun software inovatif berstandar industri, dan alat bantu beserta frameworknya membantu pekerjaan menjadi lebih mudah. Lisensi Eclipse menggunakan EPL (Eclipse Public License), yaitu lisensi yang memungkinkan organisasi untuk menjadikan Eclipse sebagai produk komersialnya, dan pada saat yang sama meminta orang yang melakukan perubahan untuk mengkontribusikan hasilnya kembali kepada komunitas. Instalasi • Anda membutuhkan Java 5 JRE untuk menjalankan Eclipse. • Download Eclipse IDE for Java Developers untuk menggunakan kode pada situs Belajar Java ini. • Gunakan utility pada sistem operasi anda untuk membuka kompresi file tersebut ke dalam hard disk anda. • Catatan untuk Windows: Apabila Anda menggunakan utilitas kompresi file yang berasal dari Windows XP atau Windows Vista itu sendiri, kadang kala utilitas tersebut tidak berhasil membuka file dengan nama yang panjang. Jika Anda mengalami masalah dekompresi Eclipse pada Windows, letakkan hasil dekompresi pada root directory (misalnya C:\eclipse) atau gunakan software dekompresi lain yang gratis seperti 7-Zip

Menjalankan Eclipse untuk pertama kali
Menjalankan Eclipse untuk pertama kali

Cari file bernama eclipse.exe (pada Windows) atau eclipse (pada Ubuntu) kemudian double-click • Pada saat Eclipse pertama kali dijalankan, Eclipse akan menanyakan workspace, yaitu folder tempat proyek dan data diletakkan. Anda bisa menempatkan di mana saja asalkan jangan di dalam folder Eclipse itu sendiri. • Click Browse dan pilih folder yang ada inginkan. Tik "Use this as default and do not ask again" • Halaman pembuka akan muncul. Klik "Workspace", tombol paling kanan berbentuk anak panah untuk masuk ke dalam workspace Anda. Program Java pertama Anda • Klik "File -> New -> Java Project" • Isi nama proyek (misalnya SelamatDatang), kemudian klik "Finish" • Setelah Eclipse membuat proyek untuk Anda, di bagian kiri workspace Anda akan melihat struktur direktori proyek Anda yang dimulai dengan nama proyek, folder src, dan folder JRE System Library • Klik kanan pada folder src, kemudian "New -> Package" • Isi nama package (misalnya selamatdatang), kemudian klik "Finish" • Klik kanan lagi pada folder selamatdatang, kemudian "New -> Class" • Isi nama class (misalnya SelamatDatang) • Karena class ini adalah class utama yang akan langsung dijalankan oleh JRE (Java Runtime Environment), click "public static void main(String[] args)" pada bagian "Which method stubs would you like to create?"

• •

• System.out.println("Selamat Datang!"); •

Klik "Finish" Eclipse akan membuat program kosong yang berisi package dan class sesuai dengan nama yang Anda masukkan pada tahap sebelumnya Sekarang ketik program berikut di bawah "// TODO"

Kemudian simpan hasilnya Menjalankan program Java pertama Anda • Untuk menjalankan program Anda, klik "Run -> Run" • Di bagian bawah pada tab yang berjudul "Console" hasil program Anda ditampilkan • Program ini akan menampilkan tulisan Selamat Datang! seperti pada gambar berikut ini

Mengimport proyek ke dalam Eclipse
Dalam situs ini, akan ada beberapa program yang cukup panjang dan mungkin menyusahkan Anda apabila harus mengetik satu per satu. Anda dapat juga mendownload berkas terkompresi untuk kemudian diimport ke dalam Eclipse. • Download file ini ke komputer Anda • Pada Eclipse, klik "New -> Import -> General -> Existing Project into Workspace" • Lalu tik "Select Archieve", pilih file yang telah Anda download tersebut, dan klik "Finish"

Instalasi Subversive, Plugin SVN untuk Eclipse
Untuk menggunakan contoh kode pada situs ini, Anda juga bisa menggunakan Subversion untuk mengambil file langsung dari gudang SVN. Untuk menginstall Plugin Subversive, dengan melakukan langkah-langkah berikut ini : 1. Klik "Help -> Software Updates -> Available Software" 2. Klik tombol "Add Site", kemudian masukkan alamatnya sebagai berikut : http://subclipse.tigris.org/update_1.4.x

3. klik "Finish". Menguji Koneksi SVN Setelah Anda berhasil melakukan instalasi plug-in Subversive. lalu klik "Install" : 4. jangan lupa untuk mengaccept license agreementnya. pilih beberapa plugin seperti pada gambar berikut. langkah-langkah berikut ini akan membimbing Anda untuk menguji koneksi ke gudang (repository) kode pada SVN server. Window baru akan muncul. Setelah mengambil data plugin yang tersedia. .

Masukkan http://belajarjava.com/svn/trunk 4. Pilih folder selamatdatang dan klik Finish 5. 6. Klik "New -> Project -> SVN -> Checkout Project from SVN" 2. Klik "Run -> Run" dan pilh "Java Application" untuk menjalankan program ini. . Project baru akan tersedia di sebelah kiri workspace Anda.1. Klik "Create a new repository location" 3.googlecode. Anda telah mempersiapkan software yang diperlukan. Selamat.

Hanya program dengan sintaks yang benar yang dapat dikompilasi atau diinterpretasi yang pada akhirnya bisa dijalankan di komputer. sintaks hanya sebagian cerita.println("Selamat Datang!"). Bahasa pemrograman berbeda dengan bahasa manusia. • Melihat lebih dekat “SelamatDatang” • Variabel dan Tipe Data • String. Suatu pekerjaan yang mungkin sederhana bagi manusia tidak dapat dimengerti oleh komputer. Sintaks bahasa pemrograman ditentukan berdasarkan apa yang bisa dilakukan oleh komputer. Di situs ini kita akan mempelajari tentang sintaks dan semantik dari dari setiap bahasa pemrograman Java. Artinya program tersebut harus benar secara logika. misalnya loop (perulangan). Kompiler akan memberikan pesan kesalahan apabila ada kesalahan dalam sintaks sehingga kita memperbaikinya. yaitu : • definisi paket (package) • komentar • definisi kelas (class) • metode main package selamatdatang. Tetapi. Sintaks mudah dihafal. karena komputer membutuhkan aturan yang lebih baku apa yang boleh dan apa yang tidak boleh dalam suatu bahasa pemrograman. Objek dan Subrutin • Operator • Intermezzo : Membaca Input dari User • Intermezzo : Mengubah String ke int dan double Melihat lebih dekat “SelamatDatang” Applikasi SelamatDatang memiliki 4 komponen. cabang (branch). tetapi semantik lebih seperti perasaan. atau fungsi.Memulai Java Program komputer adalah rangkaian instruksi yang diberikan agar komputer dapat bekerja. } } . Kita ingin program yang kita buat berjalan sesuai dengan yang kita inginkan. Untuk menjadi programmer yang sukses. kita harus mengerti secara detail sintaks dari bahasa pemrograman yang kita akan gunakan. Manusia harus memberikan petunjuk kepada komputer bagaimana melakukan suatutugas dalam bentuk bahasa pemrograman. public class SelamatDatang { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub System. Untuk itu. Aturan ini disebut sintaks bahasa.Bab III . Program yang benar secara logika disebut memiliki semantik yang benar.out. coba download dan jalankan contoh-contoh program sehingga kita dapat memahami bagaimana setiap program bekerja.

satu paket terbagi menjadi beberapa berkas (file) di mana setiap file memiliki fungsi atau tugas yang sangat khusus. tetapi hal ini merupakan kebiasaan baik untuk melatih kita berfikir secara logis dan sistematis. Definisi paket (package) package selamatdatang. Variabel dan Tipe Data . Perintah tersebut menggunakan pustaka inti Java. Untuk memudahkan penulisan dan pembagian logika suatu program. yaitu kelas Sistem. } Metode main mirip dengan fungsi main pada bahasa C/C++ di mana fungsi ini merupakan pintu gerbang dimulanya suatu program. Pada contoh aplikasi SelamatDatang di atas.. Alat bantu javadoc akan memproses komentar dokumentasi untuk membuat dokumentasi secara otomatis dari sumber program. • // text — Kompiler akan mengabaikan segala sesuatu dari // hingga akhir baris Definisi Kelas public class SelamatDatang { . Package dalam Java merupakan kumpulan dari berbagai kode yang terangkum dalam satu paket. Komentar /** * @param args */ // TODO Auto-generated method stub Komentar tidak akan diproses oleh kompiler tetapi berguna bagi programmer lain.Mari kita bahas satu per satu.println("Selamat Datang!").. Metoda main dapat dipanggil dengan menyertakan variabel. System.. Metode main Dalam bahasa pemrograman Java. paket ini hanya berisi satu buah file yang isinya terdiri dari satu kelas dan satu metode.. Definisi paket tidak selalu diperlukan. baik hanya satu variabel. Kompiler akan mengabaikan komentar dari /* hingga */. Bahasa Java memiliki 3 jenis komentar : • /* text */ — Compiler akan mengabaikan kata kata antara /* dan */ • /** documentation */ — Ini merupakan komentar yang dipergunakan khusus untuk dokumentasi. banyak variabel atau bahkan tidak ada sama sekali. setiap aplikasi harus memiliki satu buah metode main yang bentuknya seperti berikut : public static void main(String[] args) { . } Kelas merupakan bagian integral dari bahasa Java karena Java merupakan bahasa berorientasi objek. Yang terakhir adalah perintah berikut untuk menampilkan Selamat Datang pada komputer Anda.out. Di sini kita definisikan kelas SelamatDatang sebagai kelas utama. Setiap aplikasi harus terdiri dari satu kelas. misalnya satu file berfungsi untuk mendeklarasikan konstanta dan kelas. sementara file yang lain berisi implementasi kelas dan prosedurnya.

dan menyimpan hasilnya dalam jarak. Komputer menghitung pernyataan ini dan menyimpan 40 ke dalam variabel kecepatan. dan mengganti apapun yang telah disimpan sebelumnya. Variable dalam pernyataan di atas adalah kecepatan dan ekspresinya adalah angka 40.println. Hal lain yang penting adalah compound names atau nama campuran. public. Variabel bisa diibaratkan sebagai kotak penyimpanan data. Dalam bahasa pemrograman tingkat tinggi seperti Java. bukan isi kotaknya. Nama System. dan lain-lain. dan heLLOwoRLD adalah nama yang berbeda-beda. Kata-kata ini disebut reserved words (kata-kata cadangan) misalnya: class. sehingga HelloWorld. Contoh: kecepatan = 40. else. yaitu yang merupakan nama biasa yang dihubungkan dengan titik.out.println artinya System menampung out dan out menampung println. misalnya System. Atau dengan kata lain. Sekarang misalnya kita ingin melakukan perhitungan yang lebih kompleks: jarak = kecepatan * waktu Di sini. HELLOWORLD. sedangkan programmer menggunakan nama untuk memerintahkan komputer mengambil data tersebut dari memori. . Ketika komputer menjalankan instruksi ini. atau pernyataan pemberian nilai. Program melakukan manipulasi data yang disimpan dalam memori. Beberapa kata tertentu merupakan nama yang memiliki kegunaan tertentu oleh Java. Dalam bahasa mesin. walaupun tempatnya selalu sama. di mana ekspresi menyatakan apapun yang berhubungan dengan nilai suatu data. Dalam suatu program. Pernyataan ini berbentuk: variable = ekspresi.out. dan tidak dapat dipergunakan oleh programmer. angka atau karakter garis bawah '_'. while. nama merupakan rangkaian dari 1 atau lebih karakter. Nama yang digunakan seperti ini disebut variable. Harus dimulai dengan huruf dan harus terdiri dari huruf. komputer akan menghitung dan menyimpan hasilnya ke dalam variabel. Kita sebut "sesuatu" sebagai identifier (pengenal) tidak peduli apakah ia berupa nama tunggal atau campuran. static. programmer harus mengerti bagaimana aturan pemberian nama dan aturan untuk menggunakan nama tersebut dalam programnya. Komputer mengambil data yang disimpan dalam variabel kecepatan dan waktu.Nama merupakan hal penting dalam teknik pemrograman. nama digunakan untuk menyebut sesuatu. Variabel bukan isi dari data. if. nama bisa digunakan untk mengganti alamat data tersebut di memori. variabel hanya dapat dipercaya pada satu saat saja. Berikut ini adalah contoh nama yang diperbolehkan: N n rate x15 quite_a_long_name HelloWorld Hurus kecil dan huruf besar dianggap berbeda. data hanya bisa diambil dengan menyebut alamatnya di memori. melakukan perkalian. Tugas komputer adalah untuk melacak di mana data tersebut di simpan. satu-satunya cara untuk memasukkan data ke dalam variabel adalah dengan menggunakan assignment statement. tapi lokasi di memori yang menyimpan data tersebut. Menurut aturan sintaks Java. programmer harus mengerti sintaks dan semantik dari nama. Karena data di dalam kotak bisa berubah. helloworld. Untuk menggunakan "sesuatu" tersebut. * merupakan operasi perkalian. Variabel sebenarnya berarti lebih kompleks. Dalam bahasa Java. Idenya adalah "sesuatu" pada Java dapat terdiri dari "sesuatu" yang lain.

String nama. kecuali variabel tersebut berhubungan erat satu sama lain. String nama.Variabel dalam bahasa Java didesign untuk menyimpan hanya 1 jenis tipe data. Variabel yang .94065645841246544edouble Bilangan riil 64-bit 1. Pernyataan deklarasi variabel digunakan untuk mendeklarasikan satu atau lebih variabel dan memberinya nama.79769313486231570e+308 324 Suatu variabel baru dapat digunakan apabila telah dideklarasikan. Dalam bahasa pemrograman berorientasi objek. Gaya pemrograman yang baik yaitu dengan mendeklarasikan satu variabel dalam satu pernyataan. atau dapat berubah-ubah. Misalnya: float num. boolean bol = true. float angka = -1.y. Kompiler akan menampilkan kesalahan sintax apabila variabel ini dicoba untuk diberi tipe data jenis lain. Deklarasi variable berbentuk seperti : nama_tipe nama_variabel. Nilai yang terkandung dalam variabel tak-statis ini berbeda untuk setiap objeknya. Variabel ini merupakan bagian integral dari suatu kelas.40129846432481707efloat Bilangan riil 32-bit 3. nama_variabel dapat berupa sebuah nama variabel atau beberapa nama sekaligus yang dipisah dengan koma. Atau pendeklarasian variabel bisa juga dilakukan sekaligus dengan pemberian nilainya. boolean bol.504. objek menyimpan variabel yang tidak dideklarasikan dengan kata kunci static dalam kategori non-statis.40282346638528860e+38 45 4. komputer akan menyediakan ruangan di memori kemudian menyimpan alamat ini sesuai dengan nama variabel yang diberikan. dan tidak ada satu objek pun yang dapat menyatakan kepemilikan atas variabel ini. • Class Variables (statis). char ch = 'e'. Ketika komputer mengeksekusi deklarasi variabel. int x. Suatu kelas dapat dijelmakan ke dalam beberapa objek. Jenis Deskripsi Ukuran Minimum Maksimum Data Hanya bisa berisi boolean 1-bit benar atau salah char Karakter Unicode 16-bit byte Bilangan bulat 8-bit -127 128 short Bilangan bulat 16-bit -32768 32767 int Bilangan bulat 32-bit -2147483648 2147483647 long Bilangan bulat 64-bit -9223372036854775808 9223372036854775807 1. Oleh karena itu Java disebut bahasa pemrograman bertipe kuat atau strongly typed language. Jenis-jenis Variabel Java memiliki beberapa jenis variabel yang dapat dikelompokkan sebagai berikut : • Instance Variables (tidak statis). Ada 8 tipe data primitif dalam bahasa Java. seperti pada contoh berikut: int num = 1000.

yang dinamakan literal adalah 10. Misalnya int angka = 10. Literal Bilangan Bulat Bilangan bulat dapat dilambangkan dalam beberapa bentuk. Pada bahasa pemrograman java. kalimat. \r = carriage return. // 2a heksadesimal atau 42 dalam desimal int angka = 0x2a. atau boolean. Parameter. yang berarti hanya dapat terdiri dari angkaangka 0 hingga 7. int angka = -10. // huruf 'A' dalam ASCII char huruf = '\u0041'. Paramater atau argumen adalah variabel yang digunakan pada saat suatu metoda atau prosedur dipanggil. Bilangan bulat biasa dilambangkan dengan deretan angka yang dimulai dengan angka yang bukan nol. riil. Parameter berguna untuk memberikan nilai awal untuk diteruskan (pass) ke dalam suatu prosedur atau metoda. tambahkan huruf L pada akhir bilangan. Literal Karakter Kita dapat melambangkan suatu karakter dengan tanda petik tunggal misalnya ‘a’ atau ‘3′ atau ‘=’. int angka = 22L. Local Variables. . Bilangan oktal adalah bilangan bulat berbasis 8. Pada pernyataan di atas. yaitu rangkaian kata atau huruf yang menyatakan suatu nilai. Bilangan heksadesimal adalah bilangan berbasis 16. karena 10 berarti bilangan bulat atau integer. terdapat beberapa jenis literal yang melambangkan bilangan bulat. Bilangan oktal ditulis seperti bilangan bulat biasa dimulai dengan 0. yang artinya kita dapat menyimpan bilangan bulat hingga 2 ^ 64. Literal Pada bagian ini akan dijelaskan tentang literal. Suatu karakter dapat juga dilambangkan dengan kode ASCII nya. Long integer. Selain itu ada beberapa karakter lain selain alfabet yang dapat dilambangkan dengan escape sequence. \n = tombol enter atau baris baru. Seperti dijelaskan pada bab terdahulu long integer membutuhkan memori sebesar 64bit. // 22 basis delapan atau 18 dalam desimal int angka = 022. Variabel ini bersifat lokal karena hanya dapat diakses oleh metoda atau prosedur tersebut. Variabel ini lebih bersifat global yang nilainya sama untuk setiap objek pada kelas yang bersangkutan. Bilangan heksadesimal dilambangkan dengan 0 hingga 9 dan a hingga f dan dimulai dengan 0x. Caranya dengan memulainya dengan \u00 (garis miring terbalik) kemudian diikuti dengan kode ASCII nya dalam bentuk heksadesimal. Untuk merepresentasikan long integer.• • dideklarasikan sebagai statis digunakan bersama oleh semua objek. Berikut ini beberapa contohnya. Variabel ini didefinisikan di dalam suatu metoda (method) atau dalam suatu prosedur.

pada java dapat disimpan baik sebagai float atau double. Misalnya String hallo = "Selamat Datang \"Bapak Presiden\"". // Contoh string kosong String teks = "".27E+32. \\ = karakter \ \’ = karakter ‘ \” = karakter ” Literal Boolean Nilai true dan false pada java merupakan literal boolean. atau eksponen (dilambangkan dengan e atau E). Dalam bahasa java. Berikut beberapa contohnya.14159. System.\nSemoga hari anda cerah\n". // String dapat juga dipisah menjadi beberapa baris teks = "ini baris pertama " + "dan ini lanjutannya. float pi = 3. modifikasi.println("Hallo Bambang\nSelamat pagi. Java menyediakan beberapa metoda untuk melakukan penggabungan.3. Ukuran Tipe Rentang Presisi (jumlah digit) bytes bit float 4 32 +/.4 x 1038 6-7 308 double 8 64 +/. atau perbandingan. Berikut ini adalah beberapa contoh lainnya.1. tetapi merupakan kelas. String ditulis di antara dua tanda petik ganda seperti contoh berikut.\t = tombol tab. Suatu variabel bertipe boolean hanya dapat memiliki nilai true atau false. Literal Bilangan Riil Bilangan riil. pecahan. String pada java tidak disimpan dalam bentuk array seperti pada C. Ingat bahwa boolean true atau false TIDAK menggunakan tanda petik tunggal seperti ekspresi pada karakter. // Contoh string berisi " teks = "\"". misalnya -0.8 x 10 15 Imbuhan akhir d atau D dan f atau F dapat pula ditambahkan untuk menentukan tipenya secara eksplisit. double d = 3. boolean ok = true. Bilangan real dapat direpresentasikan dalam bentuk desimal biasa." Literal Null . Literal String String merupakan untaian huruf dan angka yang tersusun menjadi satu kalimat.00127 atau 415. \b = tombol backspace.out. String juga dapat mengandung karakter spesial seperti dibahas pada literal karakter. String salam = "Selamat Datang".842. float f = 4f. string bukan merupakan tipe primitif.

Berikut ini adalah contohnya obj = null. Pada saat suatu objek dideklarasikan. komputer akan mengalokasikan memori untuk objek tersebut. Kode program dapat anda unduh dalam bentuk zip file atau melalui SVN di alamat berikut : http://belajarjava. package bungabank.Instalasi. kita dapat melepas lokasi memori yang digunakan oleh objek tersebut sehingga memori itu dapat digunakan oleh objek lain. public class BungaBank { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub /* Deklarasi variable */ double pokok. . // suku bunga bank double bunga. Null merupakan kondisi di mana suatu objek tidak diberi alokasi memori. Apabila objek tersebut telah selesai dipergunakan. // nilai investasi double sukubunga. // nilai bunga /* Perhitungan */ pokok = 20000.googlecode. Contoh Program Variabel dan Tipe Data Berikut ini adalah listing program penghitungan bunga bank. Literal null berfungsi memberi tahu garbage collector (pemulung memori) bahwa objek tersebut tidak lagi terpakai.com/svn/trunk/BungaBank Lihat cara mengimpor contoh-contoh program ke dalam Eclipse di Bab II . Kemudian memori akan dilepaskan agar dapat digunakan oleh objek lain.Literal terakhir pada bahasa java adalah literal null.

System.print("Nilai investasi setelah 1 tahun adalah Rp.out.10.out. System. System. // sama dengan 10% bunga = pokok * sukubunga.out.println(bunga).sukubunga = 0.print("Bunga yang dihasilkan adalah Rp.println(pokok). "). "). /* Cetak hasil keluaran */ System.out. pokok = pokok + bunga. } } Berikut adalah hasil keluarannya : .

. Kelas terdiri dari variabel dan subrutin yang disimpan di dalamnya. Objek dan Subrutin Bagian sebelumnya memperkenalkan 8 jenis tipe data primitif dan tipe data String. setiap subrutin termasuk di dalam bagian suatu kelas atau objek. Kita bisa memanggil subrutin tersebut tanpa harus mengerti bagaimana subrutin tersebut bekerja. Nilai tipe String adalah objek yang memiliki kumpulan subrutin yang dapat digunakan untuk memanipulasi String tersetbut. Subrutin adalah kumpulan instruksi program yang digabungkan sehingga memiliki fungsi tertentu. Perbedaan mendasar antara tipe primitif dan String adalah : nilai dari tipe String berupa objek.String. Dalam bahasa Java. Java menyediakan kelas standar yang siap digunakan. yaitu sekumpulan perintah yang memiliki fungsi tertentu tanpa harus mengetahui secara detail apa yang terjadi di dalam. Di bagian ini kita akan belajar bagaimana String digunakan dan juga mempelajari konsep pemrograman penting yang lain. kelas SelamatDatang memiliki anggota main() yang merupakan anggota statis kelas itu. yaitu subrutin. Variabel dan subrutin ini disebut static member (anggota statis). seperti pada main(). Contohnya adalah pada program SelamatDatang. Sebenarnya ini adalah tujuan subrutin. Anggota yang berupa static member diberi imbuhan static. Objek akan dibahas pada bagian lain mengenai kelas (class).

Objek lain yang bertipe PrintStream bisa mengirim informasi ke tujuan lain. dan nama subrutin berbentuk hampir sama. Variabel System. tetapi lebih seperti konvensi.out. sama dengan nama variabel. Objek dengan tipe PrintStream adalah objek tempat informasi bisa dicetak. Misalnya System. di mana beberapa hal yang memiliki kesamaan . Misalnya kelas String juga menyimpan beberapa subrutin statik selain juga sebagai tipe data. Kelas di sini berfungsi seperti tipe data. konvensi yang sama akan sangat memudahkan orang lain membaca dan menguji program yang kita buat.print.print mengacu pada subrutin print di dalam objek out dalam kelas System. Setiap objek yang bertipe PrintStream memiliki subrutin bernama print yang bertugas untuk mencetak sesuatu ke medium tersebut.out merupakan objek dari kelas PrintStream. Karena variable ini berada di dalam kelas System. sedangkan nama variabel dimulai dengan huruf kecil.out. Salah satu anggotanya bernama out. . Misalnya String sebenarnya merupakan nama kelas yang disediakan bahasa Java. Tetapi subrutin harus diikuti dengan tanda buka kurung sehingga masih mudah dibedakan dengan nama variabel.dalam hal PrintStream sama-sama sebagai tempat tujuan print . ada baiknya untuk membedakannya sehingga di kemudian hari program dapat dibaca dengan jelas. Kelas standar Java menggunakan nama yang selalu dimulai dengan huruf besar. (Untuk melihat dari sisi lain. String juga berupa tipe data dan kalimat seperti "Selamat Datang!" adalah isi dari tipe data String.) Karena nama variabel. Nilai yang disimpan dalam tipe data itu adalah objek. Dalam hal ini System. dan objek itu memiliki subrutin yang bernama print. sebetulnya System.print("Selamat datang!") menampilkan pesan Selamat datang! System merupakan salah satu kelas standar Java.out merupakan suatu objek. misalnya file atau network atau ke komputer lain. Kegunaan kelas baik sebagai gabungan subrutin ataupun sebagai objek sering membingungkan. kita harus memanggilnya dengan nama lengkapnya yaitu System.Fungsi kelas yang lain adalah untuk mendeskripsikan suatu objek. Ini bukan sintaks Java.dapat digunakan dengan cara yang sama. Setiap orang bebas menggunakan konvensinya masing-masing. tetapi apabila pemrograman dilakukan secara bersama-sama. seperti pada open source programming. Ini adalah esensi dari pemrograman berorientasi objek. Subrutin ini digunakan untuk menampilkan pesan kepada user.out. PrintStream adalah salah satu kelas standar Java. nama kelas. Pengenal campuran System. yaitu memanggil subrutin print. Nama subrutin juga dimulai dengan huruf kecil. • Kelas sebagai tipe data • Kelas sebagai kumpulan subrutin dan variabel statik • Kelas Math • Kelas String Kelas sebagai tipe data Kelas sebagai tipe data Mari mulai dengan melihat kembali subrutin System.out adalah tujuan tempat print dilakukan. Contoh kelas standar lainnya adalah Math yang berisi kumpulan subrutin statik untuk melakukan berbagai perhitungan matematis.out.

(Untuk semua fungsi trigonometri.out. bukan derajat) • Fungsi trigonometri inverse. • Math. Math. Fungsi adalah subrutin yang mengembalikan (return) suatu nilai. kita tidak bisa memanggil fungsi ini seperti Math. Sebagai contoh adalah fungsi untuk menghitung akar kuadrat dari suatu bilangan. seperti arcus sin.y) menghitung xy atau x pangkat y • Math. Status 0 berarti program berhenti normal tanpa adanya error. Dan logaritma natural loge x atau ln x bisa dihitung dengan menggunakan fungsi Math. panjangDiagonal = Math. kelas System juga memiliki subrutin statik yang bernama exit.exp(x).exit akan menghentikan jalannya program.print( Math.sqrt(x) ). menghitung nilai mutlak (absolut) dari x. Karena Math.84 akan dibulatkan ke bawah menjadi 3.sqrt(x) menghitung akar kuadrat dari x dan mengembalikan hasil perhitungannya. yang mencari sudut dari suatu nilai trigonometric. atau ex. arcus cos.sqrt(x) mengembalikan suatu bilangan. • Fungsi trigonometri Math. Subrutin jenis ini disebut function (fungsi).exit(1).log(x). Beberapa yang penting di antaranya: • Math.tan(x). Setiap subrutin melakukan fungsi tertentu. misalnya 3. Math. untuk memberitahu kepada sistem operasi alasan kenapa program dihentikan. // Menampilkan akar kuadrat x di layar. Subrutin exit menerima parameter bilangan bulat.0 .sqrt. Fungsi ini merupakan anggota statik dari kelas yang bernama Math.abs(x). Beberapa di antaranya melakukan perhitungan lalu melaporkan hasil perhitungannya. // Tidak masuk akal! Kita tentunya ingin menggunakan hasilnya untuk instruksi selanjutnya. Java memiliki fungsi seperti itu yang disebut Math.floor(x) menghitung pembulatan ke bawah dari suatu bilangan riil. • Math. and Math. Ada juga yang berfungsi untuk mengambil data dari tempat tertentu dan melaporkan data yang didapat.pow(x. Nilai yang dikembalikan akan digunakan lebih lanjut dalam program. dan arcus tangen. Jika x adalah suatu bilangan. dan bilangan positif tetap bilangan positif.asin(x). menghitung pangkat dari bilangan natural e. Math.cos(x). sudut memiliki satuan radian. Memanggil System.sqrt(x).acos(x). Nilai mutlak bilangan negatif adalah bilangan positif. misalnya menuliskan hasilnya di layar seperti System.sin(x).exit(0) atau System. sedangkan status lain berarti ada sesuatu yang salah yang terjadi di tengah eksekusi program tersebut. makan Math.atan(x). misalnya System. atau menyimpan hasilnya pada variabel lain. seperti Kelas Math Kelas Math memiliki banyak fungsi statik.Kelas sebagai kumpulan subrutin dan variabel statik Kelas sebagai kumpulan subrutin dan variabel statik Selain sebagai tipe data. and Math. kebalikan dari fungsi trigonometri.sqrt(x). dan digunakan apabila karena suatu hal (misalnya program telah selesai atau adanya error) program harus dihentikan.

Satu milidetik sama dengan 1 per 1000 detik. Perbedaannya adalah waktu yang diperlukan untuk menjalankan suatu instruksi. dll).googlecode. Untuk menghitung waktu yang diperlukan untuk menjalankan suatu perintah.memilih bilangan acak di antara 0. Kode program dapat anda unduh dalam bentuk zip file atau melalui SVN di alamat berikut : http://belajarjava. menampilkan hasilnya di layar. dan melaporkan waktu yang diperlukan untuk melakukan perhitungan tersebut.random() tidak memiliki parameter.0 dan 1. tetapi tanda kurungnya harus tetap ditulis untuk membedakan fungsi dan variabel. • Math. dan melaporkan waktu yang diperlukan * untuk melakukan perhitungan tersebut * * @param args */ public static void main(String[] args) { . * menampilkan hasilnya di layar. kecuali abs(x) yang tipe keluarannya sama dengan tipe parameternya. Contoh fungsi lain yang tidak memiliki parameter adalah System.Instalasi. dihitung sejak 1 Januri 1970 waktu GMT.currentTimeMillis() yang berguna untuk mengambil waktu saat ini dalam satuan milidetik.com/svn/trunk/WaktuKomputasi Lihat cara mengimpor contoh-contoh program ke dalam Eclipse di Bab II . tetapi keluarannya bertipe double.0.currentTimeMillis() sebelum dan sesudah suatu instruksi dijalankan. int. package waktukomputasi. tetapi cukup untuk kebanyakan fungsi) Paremeter (nilai di dalam kurung) fungsi-fungsi di atas bisa bertipe numerik apa saja (misalnya double. jalankan fungsi System. public class WaktuKomputasi { /** * Program ini akan melakukan beberapa perhitungan matematika.random() Contoh Kelas Math Berikut ini adalah listing program untuk melakukan beberapa perhitungan matematika. Komputer memiliki algoritma perhitungan tertentu yang hasilnya bilangan acak (meskipun bulan bilangan yang betul-betul acak. Math. Keluarannya bertipe long.

println(Math. double panjang. System.println(sisiMiring).out.currentTimeMillis(). System. sin(x)*sin(x) + " + "cos(x)*cos(x) . lebar.1 = 0").print("sin(1)*sin(1) + cos(1)*cos(1) .0.sin(1) + Math. .out.out. System.println("(Mungkin akan ada kesalahan desimal dalam " + "perhitungan bilangan real!)"). System. System.// TODO Auto-generated method stub long waktuMulai. lebar = 27. System. System. sisiMiring.1 = "). System.random()).out.1 ). System.println("Mari kita cek untuk x = 1 :").println("\nSecara matematis.print("Segitiga siku-siku dengan panjang 18 dan lebar 27 memiliki sisi miring ").cos(1) . // sisi segitiga siku-siku sisiMiring = Math.cos(1)*Math.out.out. waktuMulai = System.sqrt(panjang*panjang + lebar*lebar). long waktuSelesai.println( Math. panjang = 18.out.sin(1)*Math.print("\nIni adalah bilangan acak : ").out.out.

print((waktuSelesai . System.out. Objek ini berisi rangkaian huruf yang membentuk string.out.0).waktuSelesai = System. Objek tersebut juga berisi subrutin.out. System. Misalnya length adalah fungsi yang menghitung panjang suatu .waktuMulai)/1000.currentTimeMillis().print("\nTotal waktu perhitungan : ").println(" detik"). } } Berikut adalah hasil keluarannya : Kelas String Nilai suatu String adalah objek. System.

Fungsi ini mengambil potongan string antara karakter ke-N hingga karakter M-1.equals(s2) adalah fungsi yang mengembalikan nilai boolean (true atau false).length() . Karakter terakhir memiliki indeks s1. Jika s1 dan s2 sama.print("Indonesia Raya". di mana N dan M bilangan bulat.substring(N. hasilnya bilangan negatif . Jika s1 kurang dari s2. Fungsi ini akan menghasilkan true jika s2 sama dengan s1. Fungsi length merupakan anggota kelas String dan dapat digunakan oleh semua data yang bertipe String. • s1. Kesamaan yang diuji adalah kesamaan persis baik kapitalnya maupun urutan hurufhurufnya. dan apabila ditemukan mengembalikan posisi awal s2 di dalam s1. sedangkan s1. misalnya program berikut menghitung jumlah karakter dalam string "Indonesia Raya" : System.M). • s1.equalsIgnoreCase(s2) juga menghasilkan nilai boolean yang menguji apakah string s2 sama dengan s1 dengan tidak membandingkan kapitalnya.charAt(N).charAt(0) berarti mengambil karakter pertama. • s1. Fungsi ini mencari string s2 di dalam string s1. panggil fungsi str. perbandingannya bergantung pada nilai ASCII-nya. s1. dan seterusnya. Seperti diulas sebelumnya.indexOf("a") menghasilkan 3.string. • s1. "Kurang dari" atau "lebih dari" mengacu pada urutannya dalam abjad jika keduanya huruf kecil atau keduanya huruf besar. "kelapa muda". Fungsi ini bisa juga digunakan untuk mencari string s2 dalam s1 setelah posisi ke-N dalam string s1. • s1.6) menghasilkan 10. fungsi ini akan mengembalikan -1.substring(1. Fungsi ini tidak membutuhkan parameter.length() yang keluarannya bertipe int.length()). Misalnya. "Kucing".indexOf(s2) mengembalikan nilai integer. System. dan jika s1 lebih besar dari s2.out. "jalan layang".compareTo(s2) membandingkan s2 dan s1.toUpperCase() adalah fungsi untuk mengubah seluruh huruf dalam s1 menjadi huruf besar. Jika kapitalnya berbeda.1.toLowerCase() berfungsi untuk mengubah huruf dalam s1 menjadi hurug kecil. Catatan bahwa karakter ke-M tidak ikut diambil. hasilnya 0.length(). Jika tidak ditemukan.indexOf("a". Kelas String memiliki beberapa fungsi di antaranya : • s1. . Fungsi ini mengembalikan karakter keN dari string s1. atau jumlah karakter dalam suatu string. str = "Hari ini cerah sekali!" Untuk menghitung jumlah karakter dalam string str.1. System.println(" karakter"). N adalah integer (bilangan bulat). hasilnya bilangan positif.length() . Dan juga bisa digunakan oleh literal string. dan salah jika tidak. fungsi ini menghitung jumlah karakter dalam string s1.charAt(1) berarti mengambil karakter ke-2. Fungsi ini akan mengeluarkan pesan kesalahan apabila N bernilai negatif atau lebih besar dari s1.4) menghasilkan "ala".print("Jumlah karakter dalam \"Indonesia Raya\" adalah "). sedangkan "kelapa muda". Misalnya. • s1. • s1.out. • s1. Karakter pertama dihitung sebagai posisi ke-0. Misalnya string str yang dideklarasikan sebagai berikut : String str.out.equalsIgnoreCase("kucing") menghasilkan true.

System. menampilkan hasilnya di layar. Misalnya " selamat pagi bu ". misalnya "jalan" + 2 menjadi "jalan2". System. yang ada sebelum atau sesudah suatu kalimat. misalnya spasi.adalah berfungsi menghapus karakter yang tak bisa dicetak. • s1. Fungsi ini melakukan perhitungan kemudian mengembalikan string baru hasil perhitungan tersebut. enter. dan melaporkan waktu yang diperlukan untuk melakukan perhitungan tersebut. Untuk s1.trim() nilai s1 tidak berubah. baris baru.googlecode.trim() Contoh Kelas String Berikut ini adalah listing program untuk melakukan beberapa contoh menggunakan kelas String.length()).trim() menghasilkan "selamat pagi bu". Nilai yang dapat disambungkan bukan hanya string dan string.out. s1. tetapi juga string dan angka.com/svn/trunk/ContohString Lihat cara mengimpor contoh-contoh program ke dalam Eclipse di Bab II . str = "Hari ini cerah sekali!".Instalasi.println("Panjang string \"" + str + "\" adalah " + str.toLowerCase().out. . Kita bisa juga menggunakan tanda + menyambung 2 string.toUpperCase().print("Jumlah karakter dalam \"Indonesia Raya\" adalah "). public class ContohString { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub // demo String. Kode program dapat anda unduh dalam bentuk zip file atau melalui SVN di alamat berikut : http://belajarjava. package contohstring. s1.length() dan operator + untuk menghubungkan karakter String str. Misalnya "mata" + "hari" menjadi "matahari".

equals("Jambu")).equalsIgnoreCase("Jambu")).out.println("\"jambu\" = \"Jambu\"? " + "jambu".println(" karakter").out.out.length()).System.println("ignore case \"jambu\" = \"Jambu\"? " + "jambu". } } Berikut adalah hasil keluarannya : Operator .out. System.print("Indonesia Raya". System. // demo equals dan compareTo System.

Operator pengurangan * Operator perkalian / Operator pembagian % Operator sisa pembagian Operator aritmatika digunakan untuk melakukan operasi matematika.1. dan modulo (atau sisa pembagian). . Contoh penggunaan : Simbol Nama operator Contoh penggunaan + Operator penjumlahan n = n + 1.out.Instalasi.out. g = y / x.println("Perkalian (x*y) : " + g). System.com/svn/trunk/OperatorAritmatika Lihat cara mengimpor contoh-contoh program ke dalam Eclipse di Bab II .println("Pengurangan (y-x) : " + g). Operator pengurangan n = n . pengurangan. g = x + y. package operatoraritmatika. / Operator pembagian n = n / 1. g = z % y. g = y . 3. % Operator sisa pembagian n = n % 1. System. System.println("Penjumlahan (x+y) : " + g). + Operator penyambung string n = "saya "+"tidur". pembagian. 5. seperti penambahan. public class OperatorAritmatika { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int int int int x y z g = = = = 2.out. System. 0. Contoh kode program yang dapat Anda unduh dalam bentuk zip file atau melalui SVN di alamat berikut : http://belajarjava.x. * Operator perkalian n = n * 1.Operator Aritmatika + Operator penjumlahan (juga sebagai penyambung string) .println("Pembagian (y/x) : " + g). g = x * y.out.println("Sisa pembagian (z%x) : " + g). System.googlecode.out.

out.Operator minus. + Operator plus menyatakan nilai positif .println("Hasilnya sekarang : " + g). dapat pula digunakan untuk menegatifkan suatu bilangan ++ Operator kenaikan. Operator ini tidak dapat digunakan untuk variabel final. membalik nilai suatu boolean Operator tunggal hanya membutuhkan satu operan untuk melakukan operasinya. menambah suatu bilangan dengan 1 -. karena variabel final berupa konstanta yang tidak dapat diubah-ubah.Operator penurunan. Beberapa jenis operator tunggal diberikan pada tabel di bawah ini. menyatakan nilai negatif. menyatakan nilai positif (setiap angka tanpa tanda ini akan dianggap sebagai positif) . Simbol Nama operator Operasi Contoh angka = +1. } } Keluaran Program : Operator Tunggal + Operator plus. System. mengurangkan suatu bilangan dengan 1 ! Operator lawan.g = x + (y * (z/x)).

System.out. System.println("Nilai x baru :" + x). x = 0.googlecode. System. package operatortunggal. angka = --angka. ok = !true.println("Contoh operator pada prefix (awalan)").out.out.out.println("Nilai y = x++ :" + y).println("---------------------------"). System. y = ++x. // sekarang angka bernilai 1 angka = ++angka.out.out. System.println("Nilai y = ++x : " + y).out.Instalasi.com/svn/trunk/OperatorTunggal Lihat cara mengimpor contoh-contoh program ke dalam Eclipse di Bab II . System. angka = -angka. y = 0. Operator kenaikan dan penurunan dapat diletakkan di belakang atau di depan suatu variabel.out. public class OperatorTunggal { /** * Contoh program menggunakan operator tunggal * * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int x = 0. penambahan/pengurangan dilakukan sebelumnya. sedangkan apabila diletakkan di akhir (x++ atau x--) penambahan/pengurangan dilakukan setelahnya. int y = 0. dapat pula digunakan untuk menegatifkan suatu bilangan menambah suatu bilangan dengan 1 mengurangkan suatu bilangan dengan 1 membalik nilai suatu boolean angka = -1.++ -! Operator minus Operator kenaikan Operator penurunan Operator lawan menyatakan nilai negatif. System.println("---------------------------"). System.println("\nContoh operator pada sufix (akhiran)"). Mari kita lihat contohnya untuk membedakan lebih jelas perbedaan penempatan operator tunggal ++ dan -Contoh kode program yang dapat Anda unduh dalam bentuk zip file atau melalui SVN di alamat berikut : http://belajarjava.println("Nilai x baru : " + x). Jika diletakkan di depan (++x atau --x). y = x++. Walau bagaimanapun pada akhirnya keduanya akan menghasilkan x = x+1 atau x = x-1. } } .

dalam hal ini operasinya dilakukan pada dua operand. Boolean dan Kondisi Operator kondisi (conditional operator) menghasilkan nilai true atau false tergantung dari variabelnya. Operator boolean adalah operator kondisi yang kedua operandnya berupa nilai boolean (true atau false). seperti String. Catatan : Pada objek. Simbol Nama operator Contoh .Jalankan program tersebut dan lihat hasilnya. Apabila operator ++ diletakkan di akhir (sufix). equalsIgnoreCase(). lalu hasilnya diberi kepada "y". Untuk membandingkan isi String. Apabila operator ++ diletakkan di awal (prefix). gunakan equals(). sedangkan Operator Pembanding membandingkan 2 nilai seperti pada operasi matematika. maka nilai "x" dan "y" akan sama. karena penambahan nilai "x" dilakukan terlebih dahulu. Baru kemudian nilai "x" ditambahkan. dan compareTo() seperti dibahas pada bagian sebelumnya. Java akan memberi nilai "y" dengan nilai "x" sebelum operasi ++ dilakukan. Berikut ini adalah screenshot keluarannya : Operator Pembanding. bukan membandingkan isinya. nilai "y" adalah nilai "x" terdahulu. operasi pembanding akan membandingkan alamat memory tempat objek itu disimpan.

apabila Op1 (di sebelah kiri) bernilai "false". hasilnya akan selalu "true" tidak tergantung pada isi dari Op2. Op1 atau Exp1 Op2 atau Exp2 Hasil true true true true false false false true false false false false Operator && akan mengevaluasi Op2 (di sebelah kanan) HANYA jika operand 1 bernilai "true". Operator NOT Operator NOT ("!") melakukan operasi boolean NOT pada operand atau ekspresi tunggal. Seperti terlihat dari tabel di atas. apabila Op1 (di sebelah kiri) bernilai "true". Jika salah satunya atau keduanya "false". Op1 atau Exp1 Op2 atau Exp2 Hasil true true true true false true false true true false false false Operator || akan mengevaluasi Op2 (di sebelah kanan) HANYA jika operand 1 bernilai "false". b = (1 == 2).== != > >= < <= && || ! ?: Sama dengan Tidak sama dengan Lebih besar Lebih besar atau sama dengan Lebih kecil Lebih kecil atau sama dengan Conditional AND Conditional OR NOT Bentuk pendek dari if-then-else b = (1 == 2). operator ini menghasilkan "false". Seperti terlihat dari tabel di atas. b = true || false. b = (1 > 2). b = !true. Berikut ini table kebenaran oeprasi OR. Operator boolean AND Operator kondisi AND menghasilkan "true" apabila kedua operandnya bernilai "true". operator ini menghasilkan "false". Jika keduanya "false". hasilnya akan selalu "false" tidak tergantung pada isi dari Op2. Berikut ini adalah tabel kebenaran operator NOT. Operator kondisi OR Operator kondisi OR menghasilkan "true" jika salah satu operandnya bernilai "true". Op1 Hasil true false . b = (1 <= 2). Operator ini mengecek nilai boolean dari suatu operand atau expresi kemudian membalik nilainya (dari true ke false atau false ke true). Berikut ini tabel kebenaran operasi AND. b = (1 >= 2). b = (1 < 2). b = true && false.

karena ekspresi (1 > 2) adalah salah (atau "false").googlecode. operator akan mengembalika "jika_salah".println("Angka yang keluar adalah " + angka). if((x == 5) && (x < y)) System.println("Nilai y lebih besar dari x"). int y = 10. angka = 0. angka = bl ? x : y.out. . operator akan mengembalikan "jika_benar". "x" akan memiliki nilai 20. boolean bl = true. tetapi apabila "kondisi" bernilai "false". Berikut adalah hasil keluarannya : Berikut adalah hasil keluarannya : Operator Pemberi Nilai & Type Casting Operator merupakan simbol untuk melakukan perhitungan atau suatu operasi pada satu atau lebih dari satu hal.out. } } System. kita dapat menggunakan operator untuk melakukan beberapa hal seperti penambahan. Apabila kondisi bernilai "true". Contoh kode program yang dapat Anda unduh dalam bentuk zip file atau melalui SVN di alamat berikut : http://belajarjava. Misalnya x = (1 > 2) ? 10 : 20 Dari contoh di atas. pengurangan dan sebagainya. Secara umum kondisi ? jika_benar : jika_salah Pada dasarnya operator "?:" akan mengevaluasi "kondisi". Setelah kita mendeklarasi dan mengisi suatu variabel.println("Nilai x adalah " + x).com/svn/trunk/OperatorKondisi package operatorkondisi.out. yang pada dasarnya merupakan bentuk pendek dari if-then-else. public class OperatorKondisi { /** * Contoh program menggunakan operator kondisi * * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int x = 5.false true Operator Ternary (?:) Java memiliki operator berkondisi lain yang disebut ternary "?:". if((x == y) || (y > 1)) System.

Kita bisa mengubah tipe apa saja. atau pergeseran bit. Pada ekspresi pertama. x = (y + z). Bagaimana jika tidak. B akan mengambil nilai A yang sudah dikonversi ke tipe short. Java melakukan type casting dengan memangkas desimalnya. Operator ini juga dapat digunakan untuk memberikan referensi kepada suatu objek. Jika variabel tersebut telah memiliki nilai. dan kemudian "y" ke "x" secara bersamaan. // buat objek baru Shape s1 = new Shape(). Perubahan tipe ini disebut type casting.Operator Pemberi Nilai = Operator pemberi nilai Operator penugasan dan pemberian nilai merupakan operator yang paling umum dalam semua bahasa pemrograman. nilai "x" akan dijumlahkan dengan 2. Selain operasi "=". boolean dewasa = true. dan dapat digunakan oleh semua operator aritmatika. A = 17. Pada dasarnya. // beri referensi s1 kepada s2 Shape s2 = s1. Beberapa contoh : String nama = "Budi". . Tanda (short) dalam kurung artinya menginstruksikan Java untuk mengubah nilai A menjadi short sebelum diberikan kepada B. Nilai char juga bisa diubah ke dalam bilangan bulat. kemudian nilai yang disimpan "z" diberikan kepada "y". Pada kode di atas. Operator "=" dievaluasi dari kanan ke kiri. tetapi karena rentang tiap tipe berbeda. manipulasi bit. nilainya akan diganti dengan variabel atau angka di sebelah kanan operator. Misalnya : x = y = z = 2. Misalnya x = A. Misalnya (short)100000 adalah -31072. Pada ekspresi kedua. short B. Operator ini dilambangkan dengan "=" yang digunakan untuk memberikan nilai kepada suatu variabel di sebelah kiri operator. angka 2 diberikan kepada "z". B = (short)A. x dan A harus memiliki tipe yang sama. Jadi 3. nilai hasil evaluasi pertambahan dimasukkan ke variabel "x". yaitu dengan menggantinya dengan bilangan Unicode-nya. Anda dapat juga memberikan nilai kepada beberapa variabel secara bersamaan. maka nilainya belum tentu sama dengan nilai aslinya. Java juga memiliki operator pemberian nilai beruntun.56 akan diubah menjadi 3 dalam bilangan bulat. kedua sisi tanda "=" harus memiliki tipe yang sama. kemudian hasilnya disimpan kembali ke "x". // nilai sebelumnya diganti dewasa = false. Table berikut menunjukkan semua operator pemberian nilai yang dapat Anda gunakan sehingga kode Anda menjadi lebih efisien dan mudah dibaca. x += 2. Misalnya pada ekspresi berikut. misalnya int A. Untuk perubahan tipe dari bilangan real (float atau double) ke bilangan bulat.

x >>= y.println("Hasil penjumlahan : " + x). x = (x / y). x ^= y. x -= y. public class OperatorPemberiNilai { /** * Contoh program menggunakan operator pemberi nilai (assignment operator) * * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int x = 5.out. . System. x %= y. x &= y.println("Sisa pembagian : " + x). x %= y. x &= y. x >>>= y. System. x = (x % y). x /= y. x < <= y. x /= y.println("Hasil perkalian : " + x). x = (x | y). System. x = (x >> y). x = (x . System. x -= y.y). x = (x * y).Operator += -= *= /= %= &= |= ^= < <= >>= >>>= Contoh x += y. x *= y. x = (x < < y). x += y. Ekspresi setara x = (x + y). x |= y.out. System. x |= y.out. int y = 10. x = (x >>> y). x *= y.println("Hasil operasi OR : " + x). System.out.com/svn/trunk/OperatorPemberiNilai package operatorpemberinilai.out. System.println("Hasil pembagian : " + x).println("Hasil operasi AND : " + x). x = (x & y).out. Contoh kode program yang dapat Anda unduh dalam bentuk zip file atau melalui SVN di alamat berikut : http://belajarjava.out.println("Hasil pengurangan : " + x).googlecode. x = (x ^ y).

println("Hasil operasi pergeseran bit ke kiri :"+ x). . Di sini saya akan menjelaskan untuk membuat program yang bisa mengambil input dari konsol teks. kita akan menggunakan GUI untuk mendapatkan interaksi dari user. yaitu BufferedReader.out yang kita gunakan untuk menampilkan pesan di layar).out. dan System. sehingga untuk mengambil input dari user diperlukan sedikit trik yang tidak sesederhana readln pada bahasa pemrograman lain. Di bagian lain.x <<= y. } } Keluaran programnya : Intermezzo : Membaca Input dari User Java bukan bahasa pemrograman untuk Console (seperti DOS atau Linux). System. InputStreamReader.in (lawan dari System. setelah kita belajar pemrograman berorientasi objek. Membaca String yang diketik oleh user di konsol Kita membutuhkan kelas yang beberapa kelas.

readLine(). Semua ini bisa dituliskan dalam satu perintah yaitu : BufferedReader br = new BufferedReader(new InputStreamReader(System.* yang berarti mengimport semua kelas dalam paket java.io.Dua kelas pertama terdapat dalam package yang dinamakan java. yaitu InputStreamReader.. Dan InputStreamReader membutuhkan media tempat baca tulis dilakukan. yaitu IOException ioe adalah jenis kesalahan yang ingin kita tangkap.. nama = br. Jika tidak ada kesalahan IO yang ditemukan. } catch (IOException ioe) { . Untuk memerintahkan Java mengambil input dari user..in.io.in)). kita harus menempatkan fungsi readLine() pada klausa try { . yaitu kesalahan yang bertipe IOException. Perintah di dalam catch { . Kelas BufferedReader adalah kelas abstrak yang menangani baca tulis ke suatu media. Parameter pada catch.. Untuk itu. } Perintah di dalam try { . yaitu System.. atau komputer sedang bekerja berat sehingga input dari user tidak bisa diambil). Kemudian kita harus juga membuat suatu objek dari kelas BufferedReader. dalam hal ini terealisasi pada objek br. } adalah perintah yang kita ingin jalankan pada situasi yang "mungkin" tidak berhasil....io (tanda * berarti semua). kita harus menambah satu baris perintah import java. Karena kita berhubungan langsung dengan sistem IO (input-output) komputer yang harus diasumsikan tidak pasti (misalnya ada masalah pada sistem keyboard. maka bagian ini akan dilewatkan (tidak dijalankan). kita gunakan fungsi readline() yang terdapat pada kelas BufferedReader. Kelas ini membutuhkan kelas lain sebagai pekerjanya. . Di sini variabel br merupakan objek yang merupakan jelmaan dari kelas BufferedReader. } adalah perintah yang akan dilakukan apabila kesalahan ditangkap. Dalam hal ini kita ingin menangkap adanya kesalahan IO.

*.exit(1).println("Kesalahan IO pada saat menanyakan nama Anda").in)).Mari kita lihat program akhir untuk mengambil input dari user.out. // tempat di mana input dari user akan diletakkan String nama = null.out. } catch(IOException ioe) { System. public class AmbilInputKonsol { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub System. package ambilinputkonsol.print("Masukkan nama Anda : "). import java. .readLine(). try { nama = br. // buat objek baru untuk mengambil input BufferedReader br = new BufferedReader(new InputStreamReader(System.io. System.

com/svn/trunk/AmbilInputKonsol Untuk menguji program tersebut. Masukkan nama Anda. } } Program tersebut dapat Anda unduh dalam bentuk zip file atau melalui SVN di http://belajarjava.googlecode. .} System.out. jalankan "Run -> Run" atau Ctrl-F11. kemudian hasilnya akan ditampilkan pada baris berikutnya. Kemudian arahkan kursor Anda ke bagian bawah di kotak yang bernama Console.println("Terima kasih. " + nama).

Tetapi karena keluaran dari readLine() bertipe String.io. rumus tersebut bisa dituliskan dengan ekspresi berikut akhir = awal * Math.pow(1 + bunga. kita menggunakan kelas Java Double yang di dalamnya memiliki fungsi parseDouble(str).parseDouble(strawal). strawal = br. misalnya hasil input dari konsol atau dari hasil bacaan file. Fungsi ini dapat dipanggil dengan: awal = Double. kita bisa mengambil input tersebut menggunakan kelas BufferedReader seperti berikut.readLine().readLine().readLine(). Setelah semua variabel didapat dan diubah. ke tipe data bilangan untuk pengolahan lebih lanjut. public class HitungInvestasiNPeriode { . kita harus mengubahnya menjadi bentuk bilangan agar dapat diproses lebih lanjut.*.parseInt(strperiode). bunga = Double. Untuk menghitung bunga bank setelah n tahun.readLine(). strbunga = br. kita bisa menggunakan rumus berikut : akhir = awal * (1 + bunga)periode Dalam Java.parseDouble(strbunga). Fungsi ini dapat dipanggil dengan: periode = Integer. import java. kita baru bisa untuk memulai perhitungan. kita akan membuat program untuk menghitung nilai investasi setelah n tahun. Input yang diminta dari user adalah : • Nama • Investasi awal (Rp) • Bunga (%) • Periode (tahun) Dengan menggunakan teknik yang sama pada contoh sebelumnya. Untuk mengubah String menjadi int. nama = br.com/svn/trunk/HitungInvestasiNPeriode package hitunginvestasinperiode. kita dapat menggunakan kelas Java Integer yang di dalamnya memiliki fungsi parseInt(str). Sebagai contoh. Sedangkan untuk mengubah String menjadi double. strperiode = br. Berikut ini adalah listing program lengkap yang dapat diunduh dalam bentuk zip file atau melalui SVN di alamat http://belajarjava.googlecode.Intermezzo : Mengubah String ke int dan double Kita dapat mengubah tipe data String.periode).

awal = Double. // tampilkan hasil perhitungan di layar System.print("Masukkan jumlah awal investasi (Rp) : ").out. // menghitung hasil investasi selama n periode akhir = awal * Math. // tempat di mana input dari user akan diletakkan String nama = null.parseDouble(strawal).println(). try { System.pow(1+bunga.out. bunga = Double. tahun "). // deklarasi variabel tipe bilangan double awal. String strperiode = null. System.out. " + nama). double akhir. System. String strbunga = null. " + akhir). nama Anda").out.out. System.print("Masukkan bunga (mis 0.readLine().println("Kesalahan IO pada saat menanyakan } System. strawal = br. } catch(IOException ioe) { System.println("adalah Rp. periode). nama = br. int periode. System. // mengubah input dari Sting ke tipe data bilangan periode = Integer.1 = 10%) : ").parseDouble(strbunga).readLine(). System. .print("Hasil investasi Anda setelah " + periode + " System./** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub // buat objek baru untuk mengambil input BufferedReader br = new BufferedReader(new InputStreamReader(System.readLine().readLine().exit(1).print("Masukkan nama Anda : "). double bunga. strbunga = br.in)).parseInt(strperiode). strperiode = br.println("Terima kasih.out.out.out.out. String strawal = null.print("Masukkan periode (tahun) : ").

yaitu perulangan (loop) dan percabangan (branch). dan Percabangan Kemampuan suatu program untuk melakukan tugas kompleks dilakukan dengan menggabungkan perintah sederhana menjadi struktur kontrol. pernyataan if. Perulangan. dapat digunakan untuk mengulangi perintah berulang-ulang atau untuk memilih dua atau lebih skenario. perulangan while. ada 6 struktur tersebut. yaitu blok. akan dijelaskan lebih lanjut tentang struktur kontrol. Lebih khusus. while. Blok. dan kemudian akan kita gunakan dalam beberapa contoh yang tersedia. Kita akan melihat sebagian jawabannya di bab ini. dan pemanggilan subrutin -. kita akan melihat bagaimana komponen dasar tersebut berinteraksi sehingga menjadi program yang lebih kompleks. perulangan for. perulangan do . ekspresi. Struktur kontrol.variabel.. Bab ini juga akan membahas tentang desain suatu program.Memulai Java Lebih Lanjut Struktur Kontrol Komponen mendasar dari suatu program -. dan pernyataan switch..} } Berikut ini adalah hasil keluarannya : Bab IV . bagaimana caranya kita berfikir untuk merancang program tersebut. tetapi di dalamnya terdiri dari satu atau lebih perintah sehingga keseluruhannya menjadi suatu struktur perintah.telah dijelaskan pada Bab sebelumnya. Jika kita dihadapkan pada suatu permasalahan yang akan dipecahkan oleh program komputer. Blok . Pada bab ini. Dalam bahasa Java. penyataan. kompleksitas program akan lebih dititikberatkan pada apa yang bisa dilakukan dari dalam sebuah subrutin. Java memiliki beberapa struktur kontrol dan kita akan lihat secara lebih detail kemudian. Mulai dari bab ini. Masing-masing struktur ini sebetulnya merupakan pernyataan tunggal yang berdiri dengan sendirinya.

.out.Blok adalah pernyataan sederhana yang dimulai dengan { dan diakhiri dengan }. Konsep "scope" atau jangkauan pada konsep pemrograman. Variabel ini disebut variabel lokal. mengacu pada bisa atau tidaknya suatu variabel dilihat oleh bagian program lain. Tujuannya untuk mengelompokkan beberapa perintah sehingga lebih dimengerti. Contoh sederhana penggunaan blok ini adalah dalam subrutin main() yang kita lakukan pada contoh-contoh sebelumnya. { System. tetapi sebetulnya tanpa struktur kontrol pun. komputer akan melepas memori yang digunakan dalam blok ini untuk digunakan oleh bagian program lain. Berikut ini adalah 2 contoh penggunaan blok.out. komputer akan mempersiapkan memori untuk menyimpan variabel yang dideklarasikan di dalam blok ini.println("Hallo"). Jangkauan suatu variabel menyatakan di bagian mana variabel ini valid atau dengan kata lain bisa diakses. variabel apapun yang dideklarasikan tidak akan dapat diakses dari luar blok ini. System.println("Dunia"). Ketika komputer menjalankan program ini. kita mendeklarasikan variable baru temp. } Pada blok kedua. } { // blok ini digunakan untuk menukar isi variable x dan y int temp. temp = x. x = y. Dalam blok kedua ini. y = temp. karena hanya bisa diakses dari dalam blok. Ketika blok ini selesai dijalankan. Misalnya { perintah } Pernyataan blok biasanya terdapat dalam struktur kontrol. blok tetap berlaku. Jangkauan variabel dalam suatu blok terbatas hanya pada blok tersebut.

dan jika tidak. program akan kembali pada awal pernyataan while. jika suatu_kondisi bernilai false. program akan mengevaluasi apakah angka <= 5."). Setelah komputer sampai pada bagian akhir blok. Sekarang angka bernilai 2. yaitu : perulangan dan percabangan. Perulangan Sebagai contoh untuk membahas tentang perulangan. program akan melompat ke bagian program berikutnya setelah blok berakhir. // cetak isi angka di layar angka = angka + 1. Begitu seterusnya hingga angka bernilai 6. Ketika komputer sampai pada pernyataan while. Sekarang angka bernilai 2. dan karena 2 masih kurang dari atau sama dengan 5.println("Selesai. Ketika program sampai pada pernyataan while. Secara umum struktur kontrol dibagi menjadi 2 bagian. } // tambah angka dengan 1 System. Berikut ini adalah contoh untuk menulis bilangan 1 hingga 5. kita mulai dengan mengisi variabel angka dengan 1 while (angka <= 5) { System. komputer akan melakukan perhitungan pada suatu_kondisi.println(angka). blok yang berisi perintah akan dilakukan. program akan kembali mengeksekusi perintah dalam blok. komputer akan menghitung kembali suatu_kondisi. kita lihat pernyataan while. Pada saat ini . Setelah sampai pada akhir blok. Variabel angka kita inisialiasi (persiapkan) dan kita isi mula-mula dengan 1. sehingga pernyataan angka <= 5 bernilai true. Atau dengan kata lain.out. int angka = 1. Program akan berjalan seperti biasa dari atas kebawah seperti biasa. kemudian menambah angka dengan 1. angka masih bernilai 1. maka blok tersebut akan dieksekusi.. blok perintah tidak akan dieksekusi. Jika masih bernilai true..Blok sendiri sebetulnya bukan merupakan struktur kontrol.out. Dalam hal ini perintah di dalam blok akan dieksekusi. yang memiliki bentuk seperti while (suatu_kondisi) { perintah } Semantik pada pernyataan while tersebut adalah sebagai berikut. Pada saat program baru dimulai. // inisialisasi variabel. yaitu mencetak angka ke layar. Apabila suatu_kondisi bernilai true.

sehingga pernyataan di atas dapat ditulis juga sebagai berikut if (suatu_kondisi) { perintah_1. Percabangan Pernyataan if memperintahkan komputer untuk memilih salah satu aksi yang akan dilakukan. nilai x akan selalu bernilai lebih kecil dari y. if (x > y) { // jika x lebih besar dari y // blok ini digunakan untuk menukar isi variable x dan y int temp. } Ketika komputer sampai pada pernyataan if.. Sebagai contoh. Bentuknya dapat ditulis sebagai berikut if (suatu_kondisi) perintah_1. Jika iya.. maka blok perintah berikutnya akan dieksekusi. yaitu perintah_2.". temp = x. maka blok setelah pernyataan else akan dieksekusi. else perintah_2. kemudian melakukan perintah berikutnya. setelah program ini dieksekusi. komputer akan menghitung apakah suatu_kondisi bernilai true. mari kita kembali pada contoh program untuk membalik nilai x dan y. y = temp. dengan syarat x harus lebih besar dari y. dalam hal ini perintah_1. Perintah_1 dan perintah_2 juga bisa berbentuk blok. yaitu menampilkan kata "Selesai. x = y.program akan berhenti melakukan perulangan dan berhenti melakukan eksekusi perintah di dalam blok tersebut. nilai x akan ditukar dengan nilai y. Dalam hal ini. tergantung pada suatu kondisi tertentu. karena jika nilai x lebih besar. } . } else { perintah_2. Jika tidak.

misalnya menghitung sisi miring dari segitiga siku-siku. Semoga bagian ini yang merupakan bagian pendahuluan tentang struktur kontrol dapat dimengerti sehingga kita bisa mempelajari konsep yang lebih kompleks lagi. } Kita akan bahas tentang struktur kontrol di bagian berikutnya. Atau dengan kata lain. orang akan lebih mudah membuat suatu algoritma. . Untuk itu programmer baru harus dilengkapi dengan cara berfikir dan peralatan yang memungkinkan mereka untuk sukses dalam menerjemahkan suatu tugas menjadi rangkaian perintah yang bisa dimengerti oleh komputer.Contoh berikut adalah program untuk menentukan apakah suatu bilangan merupakan bilangan genap atau bilangan ganjil.println(x + " adalah bilangan ganjil"). algoritma mirip seperti ide di belakang program yang akan kita tulis. Programmer adalah orang yang bertugas untuk menerjemahkan suatu tugas menjadi instruksi detail yang dapat dimengerti oleh komputer. maka bilangan tersebut adalah bilangan ganjil. sisi miring dapat dihitung dengan mengambil akar kuadrat dari jumlah kuadrat sisi siku-sikunya. Pemecahan masalah ini kemudian diterjemahkan ke dalam bahasa pemrograman yang berupa perintah langkah demi langkah bagaimana komputer harus menyelesaikan tugas tersebut. Jadi darimana algoritma itu datang? Biasanya orang harus membuat algoritma itu. maka bilangan tersebut merupakan bilangan genap. Kemudian dia akan berfikir tentang apa yang harus dilakukan untuk menyelesaikan tugas tersebut dalam bahasa manusia. algoritma adalah kumpulan langkah-langkah sederhana yang jelas. Dengan menggunakan operator %. Tetapi ide tersebut harus jelas. tidak membingungkan karena hanya ada satu cara untuk melakukan langkah sederhana tersebut. if ((x % 2) == 0) { System. latihan dan pengalaman. dalam bahasa manusia. sehingga bisa diimplementasikan menggunakan bahasa pemrograman apapun. Perintah langkah demi langkah hingga detail ini disebut algoritma. Kita tidak ingin program menghitung selamanya tanpa batas waktu. tetapi komputer tidak bisa berfikir bagaimana melakukan suatu tugas seefisien mungkin. Program komputer itu seperti seni yang memuat suatu ide. yaitu sisa pembagian.out. kita harus memberikan perintah hingga sangat detail apa yang harus dikerjakan oleh komputer. (Secara teknis. kita dapat menentukan apabila sisa pembagian suatu bilangan dengan 2 adalah 0. Komputer hanya melakukan apa yang diperintahkan baris demi baris. Jika tidak.out.) Program ditulis dalam bahasa pemgrograman tertentu. Tetapi algoritma ditulis secara umum atau generic. dan memuat langkah demi langkah yang sederhana.println(x + " adalah bilangan genap"). Seorang programmer mulai dengan suatu tugas di kepalanya. Perancangan Algoritma Komputer itu bodoh! Kenapa? Karena sebagai programmer. } else { System. Dalam hal ini misalnya. dilakukan selama kurun waktu tertentu. Dengan skill.

kita bisa membuat langkah-langkah lain yang lebih detail. Jadi bahasa Java akan kita tinggalkan sementara. Selain itu kita juga harus menginisialisasi pembaca dan tempat meletakkan string sementara. Kita bisa menuliskan pseudocode dalam bentuk berikut : ambil input user untuk bilangan pertama masukkan ke variabel x ambil input user untuk bilangan kedua tambahkan variabel x dengan bilangan kedua ambil input user untuk bilangan ketiga tambahkan variabel x dengan bilangan ketiga ambil input user untuk bilangan keempat tambahkan variabel x dengan bilangan keempat ambil input user untuk bilangan kelima tambahkan variabel x dengan bilangan kelima bagi variabel x dengan 5 tampilkan hasilnya di layar Algoritma di atas betul. Untuk itu. Salah satu cara untuk menyelesaikan tugas itu adalah menuliskan penyelesaiannya langkah demi langkah. Misalnya. ambil input user bisa dideskripsikan lebih jauh.Di bagian ini akan dibahas tentang bagaimana membuat suatu algoritma. Misalnya. misalnya while a kurang dari 5 ambil input user untuk bilangan ke-a tambahkan nilai x dengan bilangan ke-a tambah a dengan 1 bagi variabel x dengan 5 tampilkan di layar Sekarang. Kita akan beralih untuk berfikir secara abstrak. Kemudian dari setiap langkah tersebut. kita bisa mulai menuliskan algoritma dalam bentuk pseudocode (kode palsu) yang bentuknya tidak harus persis atau mengikuti suatu bahasa pemrograman. dan sifatnya top-down atau dari atas ke bawah. Metode ini disebut penghalusan bertahap (stepwise refinement). tetapi terlalu banyak perulangan. kita bisa dihadapkan pada permasalahan IO (input output). Sambil kita menambah detail pada setiap langkah. Pseudocode di atas dapat ditulis ulang sebagai berikut : while a kurang dari 5 beri pertanyaan kepada user untuk memasukkan bilangan ke-a ambil input user untuk bilangan ke-a ubah input menjadi bilangan tambahkan nilai x dengan bilangan ke-a tambah a dengan 1 bagi variabel x dengan 5 tampilkan di layar Dan juga dari pelajaran sebelumnya. Bagaimana jika bilangan yang akan dirata-ratakan ada 100? Kita bisa udah algoritma di atas dengan pseudocode yang lebih mudah dimengerti. untuk mengambil input user. Dan seperti dipelajari pada bab sebelumnya. kita ambil contoh untuk menghitung rata-rata dari 5 bilangan. sampai kita bisa menerjemahkan langkah-langkah itu ke dalam bahasa pemrograman. Kita harus memberikan pertanyaan kepada user. kita memiliki suatu tugas di kepala. input dari user berupa String yang harus diterjemahkan ke dalam tipe data bilangan untuk bisa dikalkulasi. dan dari sana kita membuat algoritma untuk menyelesaikan masalah itu. kita harus mengubah pseudocode nya menjadi seperti ini inisialisasi pembaca .

System. int a = 0.println("Kesalahan IO. sehingga kita harus menambah import java. try { strbilangan = br. perlu diperhatikan bahwa variabel a dan x tidak diketahui nilai awalnya oleh komputer.io. .*. Untuk itu kita harus tambahkan perintah untuk menginisialisasi a dan x dengan 0.print("Masukkan bilangan ke-" + a + " : "). } catch (IOException ioe) { System. program berhenti"). String strbilangan = null.inisialisasi tempat string sementara while a kurang dari 5 beri pertanyaan kepada user untuk memasukkan bilangan ke-a "coba" ambil input user untuk bilangan ke-a jika ada masalah keluar dari program ubah input menjadi bilangan tambahkan nilai x dengan bilangan ke-a tambah a dengan 1 bagi variabel x dengan 5 tampilkan di layar Kemudian.in)). yaitu double x = 0.io. } x = x + Double.out.parseDouble(strbilangan).println("Rata-rata bilangan yang dimasukkan adalah " + x). while (a < 5) { System. System.exit(1). BufferedReader br = new BufferedReader(new InputStreamReader(System. Jangan lupa bahwa program tersebut membutuhkan paket java. bukan saja hasil rata-ratanya menjadi tak tentu. tetapi juga perulangannya menjadi tak menentu. Bayangkan jika nilai a dan x ditentukan oleh komputer secara acak.* di awal kelas.readLine(). } x = x / 5.out. sehingga pseudocodenya menjadi inisialisasi x dengan 0 inisialisasi a dengan 0 inisialisasi pembaca inisialisasi tempat string sementara while a kurang dari 5 beri pertanyaan kepada user untuk memasukkan bilangan ke-a "coba" ambil input user untuk bilangan ke-a jika ada masalah keluar dari program ubah input menjadi bilangan tambahkan nilai x dengan bilangan ke-a tambah a dengan 1 bagi variabel x dengan 5 tampilkan di layar Dari sini kita bisa menerjemahkan pseudocode tersebut menjadi program Java.out. a = a + 1.

import java.*.io. System. a = a + 1.exit(1).print("Masukkan bilangan ke-" + a + " : ").parseDouble(strbilangan).com/svn/trunk/HitungRataRata5Bil package hitungratarata5bil. String strbilangan = null. while (a < 5) { System. } x = x + Double.println("Kesalahan IO. } catch (IOException ioe) { System.googlecode. } Untuk menguji program tersebut. } x = x / 5. System. jalankan "Run -> Run" atau Ctrl-F11. program berhenti"). try { strbilangan = br.in)). Kemudian arahkan kursor Anda ke bagian bawah dan klik di kotak yang bernama Console.Berikut ini adalah program lengkapnya dan dapat diunduh dalam bentuk zip file atau melalui SVN di alamat berikut http://belajarjava.readLine(). public class HitungRataRata5Bil { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub double x = 0.out. .println("Rata-rata bilangan yang dimasukkan adalah } " + x). BufferedReader br = new BufferedReader(new InputStreamReader(System.out.out. int a = 0.

Berikut ini adalah hasil keluarannya. Anda bisa mencoba-coba dengan bilangan apapun. Kita tinggal memencet tombol run. dan mencari kesalahan (debugging) Akan sangat sederhana dan indah apabila program yang kita tulis akan berjalan 100% tanpa kesalahan sama sekali. Membuat kode. dan semuanya berjalan sesuai rencana. . Nyatanya tidak demikian. menguji.

Bagi beberapa programmer. Idealya apabila program menerima input yang tidak sesuai dengan yang diharapkan. atau objek dengan mudah. yang merupakan bahasa dengan sintaks ketat. mana yang berupa subrutin. Sintaks adalah salah satu cara menentukan bagaimana komputer harus bekerja. dan Anda harus memperbaikinya sebelum program bisa dijalankan. Kemudian pada Eclipse. atau format penulisan program ada memiliki kesalahan. sintaks membantu komputer mengelola logika. mana perulangan. kecuali dengan membuat variabel baru dengan tipe yang berbeda. . mana percabangan dan lain-lain. jalankan dengan "Run -> Run". Bagi komputer. Ketidakluwesan Java membantu programmer harus menggunakan logika yang benar.Coba Anda ganti salah satu dari beberapa contoh yang sudah diberikan dengan mengganti salah satu kurung { menjadi (. program akan memberikan pesan kepada penggunanya tentang kesalahan tersebut. Debugging Ketika program Anda tidak menunjukkan kesalahan sintaks. perbedaan sintaks sedikit saja membuat Java tidak mengerti apa yang dimaksud dalam program. dan tidak boleh salah dalam menggunakan variabel. itu artinya secara sintaks. Lihat apa yang terjadi. predikat. Eclipse akan menampilkan pesan kesalahan. ketidakluwesan Java mungkin menghambat. bahkan untuk kalimat yang belum pernah dibaca atau didengar sekalipun. bukan berarti program Anda bebas dari kesalahan. Dalam bahasa Java. tetapi perlu diingat bahwa kesalahan hanya datang dari manusia. mana yang merupakan variabel. Manusia tidak membutuhkan sintaks untuk berbicara karena manusia bisa menentukan mana subjek. Variabel yang sudah ditentukan tipenya tidak dapat diubah ditengah jalan. bukan tiba-tiba keluar tanpa pesan. Program harus diuji apakah ia berjalan sesuai dengan yang diharapkan.

maka mencari kesalahan yang kelihatannya sederhana tidaklah mudah. program berhenti di baris double x=0. dan bahkan mengganti variabel pada saat program dijalankan. Apabila jumlah baris dalam program kita kecil. Tetapi apabila program tersebut sangat besar. Untuk mendemonstrasikan debugging ini. Pencarian kesalahan ini dalam bahasa pemrograman disebut dengan "debugging". tetapi sebelum kita melakukannya. debugging yang bisa dilakukan antara lain: membuat breakpoint (tempat berhenti program).Kita mungkin harus melakukan testing secara lebih perlahan-lahan. Misalnya pada tampilan berikut. Perhatikan juga bahwa baris yang diberi breakpoint memiliki tanda bulat di sampingnya. Untuk menghapus breakpoint. Menjalankan program hingga breakpoint . melihat isi variabel saat ini. kita harus memberhentikan program tersebut di satu tempat terlebih dahulu. mari kita gunakan program menghitung rata-rata pada bagian terdahulu. Untuk mengeset breakpoint. yang jika diterjemahkan ke dalam bahasa Indonesia berarti membersihkan kutu. Membuat breakpoint Kita bisa menjalankan program baris demi baris. mengeksekusi satu subrutin. Eclipse menyediakan peralatan untuk melakukan debugging. karena kesalahan kecil dianggap sebagai kutu yang mengganggu jalannya program.. mengeksekusi satu demi satu perintah. Dalam Eclipse. Tempat pemberhentian program sementara ini disebut breakpoint. double klik bagian paling kiri dari baris di mana Anda ingin program tersebut berhenti. yaitu dengan menekan tombol "Run -> Debug". mungkin kesalahan tersebut dengan mudah akan kita temui. double click lagi tanda bulat di baris yang sudah diberi breakpoint tadi.

Coba tekan tombol F11 atau "Run -> Debug". Eclipse akan memberikan pertanyaan bahwa perspective (atau tampilan Eclipse) Anda akan diubah ke debugging perspective. Perhatikan bahwa di samping tanda bulat tadi. Di samping kanan adalah daftar . ada tanda panah (->) yang menunjukkan saat ini komputer telah melaksanakan program hingga pada baris ini. Pada saat Anda memulai debugging. Berikut ini adalah perspektif dalam mode debugging. Tekan Yes untuk mengubah perspective tersebut.

Berikut ini adalah screen shot setelah program maju satu langkah. maka hanya satu variabel yang tersedia. Mari kita coba untuk menjalankan progam satu langkah dengan menggunakan "Run -> Step Over" atau tombol F6. semuanya terdapat dalam menu Run yaitu : • Resume melanjutkan eksekusi program yang berhenti. Menjalankan program langkah per langkah Apabila Anda sudah berada dalam mode debugging. Anda bisa melakukan navigasi untuk melakukan eksekusi sesuka Anda. • Step Over mengeksekusi SATU perintah. maka subrutin tersebut akan dieksekusi tanpa masuk ke dalam subrutin yang dipanggil tersebut. • Run to Line menjalankan program dari baris tempat berhentinya program sekarang hingga baris yang Anda tentukan. Jika perintah tersebut merupakan perintah panggilan subrutin. Perhatikan bahwa tanda panah maju satu langkah. . • Step Return mengeksekusi seluruh perintah pada subrutin ini kemudian kembali kepada pemanggilnya. Karena baris yang kita pilih adalah baris pertama setelah deklarasi pada subrutin main. yaitu yang berasal dari arg. Dan juga karena instruksi pada baris ini adalah mendeklarasikan variabel x bertipe double. Atau jika di antaranya terdapat breakpoint lagi. variabel ini akan muncul di kanan atas perspektif Debug. • Step Into mengeksekusi SATU perintah atau masuk ke dalam subrutin. Ada beberapa pilhan yang disediakan oleh Eclipse.variabel yang dideklarasikan dalam program ini. dan kemudian mengisinya dengan 0. • Suspend menghentikan sementara program yang sedang jalan. • Terminate menghentikan sesi debugging saat ini. maka program akan berhenti di breakpoint tersebut.

Perlu diingat. klik bagian bawah (tab yang bernama Console). dan masukkan angka sebagai input kemudian tekan Enter. dan Anda akan melihat langkah demi langkah bagaimana program dijalankan secara bertahap. Lihat bagaimana variabel di kanan atas berubah sesuai dengan input yang Anda berikan. . Melihat dan mengubah isi variabel Di sini saya jalankan program setiap baris hingga a = a + 1 seperti pada gambar berikut. pada saat program sampai pada instruksi untuk mengambil input Anda.Lakukan terus Step Over hingga program berakhir.

misalnya dengan "Run -> Resume". tetapi 6 kali. saya ingin memperpanjang perulangan. yang artinya user diperintahkan untuk memasukkan 6 . yaitu dengan mengubah nilai a menjadi -1. Setelah diganti coba jalankan program hingga selesai. kemudian diganti menjadi -1. Jangan lupa untuk memasukkan inputnya di bagian Console. seperti pada screen shot berikut. Ini bisa dilakukan yaitu dengan mengklik nilai dari a. yang semula 0. sehingga bukan melakukan 5 kali perulangan. Lihat sekarang bilangan ke-0 ditanyakan 2 kali.Kemudian.

apakah program keluar dari perulangan saat itu juga? Dalam hal ini. Klik perspektif Java untuk mengubahnya menjadi tampilan semula. baru program akan melompat ke perintah berikutnya di luar blok. Anda mungkin ingin mengubah perspektif kembali seperti semula. klik tanda >> kemudian pilihan akan muncul. Program akan melompat ke perintah berikutnya di luar blok perulangan. Tentunya hasil rata-ratanya salah. karena perhitungan rata-rata dilakukan dengan rumus x = x/5. di bagian paling kanan (lihat gambar dibawah).bilangan. while dan do . Setelah itu program akan kembali ke pernyataan while. dan setelah mengevaluasi kembali suatu_kondisi. dan jika hasilnya salah. Inti perulangan akan terus dieksekusi selama suatu_kondisi bernilai true.. perintah ini disebut juga dengan inti perulangan. suatu_kondisi ini disebut juga penguji perulangan. tentunya tidak. Lalu apa yang terjadi jika suatu_kondisi bernilai false di tengah-tengah perulangan. Caranya. Program akan mengeksekusi semua perintah hingga akhir blok selesai. Perulangan while memiliki bentuk while (suatu_kondisi) perintah perintah bisa juga berupa blok yang berisi kumpulan perintah-perintah di antara { dan }. . Ada beberapa hal yang mungkin jadi pertanyaan.. Setelah selesai melakukan debugging. while Pernyataan while Pernyataan while telah diperkenalkan pada bagian sebelumnya. Apa yang terjadi jika suatu_kondisi sudah bernilai false sejak pertama kali komputer sampai pada pernyataan ini? Dalam hal ini blok perulangan tidak akan dieksekusi sama sekali. dalam hal ini seharusnya adalah 6.

*. Kita bisa ubah algoritma di atas menjadi program Java sebagai berikut. kita akan tanyakan lagi kepada user untuk mendapatkan kondisi untuk mengevaluasi kondisi while berikutnya. kita tempatkan pertanyaan untuk mendapat input dari user di akhir perulangan.googlecode. kita bisa mendapat nilai input untuk dievaluasi pada pernyataan while. komputer tidak tahu apa-apa.io. Artinya. kemudian program akan berhenti jika masih ada data yang akan diproses. program tidak akan menghitung nilai 0 lagi. Pada saat komputer pertama kali menemui perulangan while. kita tanyakan user terlebih dahulu sebelum perulangan while. Masalah ini sangat amat umum ditemui oleh programmer. (Seperti biasa program ini bisa diunduh dalam bentuk zip file atau di alamat SVN berikut: http://belajarjava. karena menghitung satu demi satu ternyata tidak mudah. bagaimana menentukan masih ada data yang akan diproses? Cara yang paling mudah adalah melihat apakah nilai yang dimasukkan user bernilai 0. import java. kita akan sedikit ubah algoritma kita seperti berikut : Inisialisasi jumlah dengan 0 Inisialisasi n (berapa data yang dimasukkan user) dengan 0 Minta input dari user while (input tidak sama dengan 0): Tambah jumlah dengan input dari user Tambah n dengan 1 Minta input dari user Bagi jumlah dengan n untuk menghitung rata-rata Cetak rata-rata ke layar Pada dasarnya. Nol hanya berfungsi sebagai sinyal bahwa perulangan harus selesai. Di algoritma sebelumnya.com/svn/trunk/RataRata ) package ratarata. padahal 0 bukan data. Perhatikan juga bahwa ketika 0 dimasukkan. Inisialisasi jumlah dengan 0 Inisialisasi n (berapa data yang dimasukkan user) dengan 0 while (masih ada data yang akan diproses): Minta input dari user Tambah jumlah dengan input dari user Tambah n dengan 1 Bagi jumlah dengan n untuk menghitung rata-rata Cetak rata-rata ke layar Pertanyaan berikutnya.) Dalam hal ini. Lalu bagaimana kita harus menguji bahwa data yang dimasukkan bernilai 0 atau bukan? (Ingat. Nol di sini bukan termasuk data yang akan dijumlahkan tetapi bertugas sebagai sinyal bahwa tidak ada lagi data yang harus dimasukkan. nilai 0 akan ikut dijumlahkan dan n akan bertambah 1.Mari kita ubah sedikit algoritma yang kita buat di bagian sebelumnya. Dengan cara ini. Di dalam perulangan while. Untuk itu debugger diperlukan untuk melihat lebih detail apa yang dilakukan oleh komputer. public class RataRata { /** * @param args */ . Kali ini kita akan membuat program yang menghitung rata-rata dengan cara menanyakan suatu bilangan kepada user. setelah kita memproses input dari user. kita baru menanyakan data di dalam blok perulangan.

System.println("Rata-rata bilangan yang dimasukkan adalah " + ratarata). BufferedReader br = new BufferedReader(new InputStreamReader(System.exit(1). double bilangan = 0. // cetak hasilnya ke layar if (n == 0) { System.out.out. try { strbilangan = br. // sama dengan : jumlah = jumlah // sama dengan : n = n+1 + bilangan // tanya user input System.out. } // mengubah input menjadi double agar bisa diproses lebih lanjut bilangan = Double. program berhenti"). } lanjut } // mengubah input menjadi double agar bisa diproses lebih bilangan = Double.out.parseDouble(strbilangan).out.exit(1). } catch (IOException ioe) { System. // hitung rata-rata double ratarata = jumlah/n. } else { System.readLine(). try { strbilangan = br. System.readLine().print("Masukkan bilangan berikutnya (atau 0 untuk mengakhiri) : "). } } } .println("Kesalahan IO.println("Data kosong.println("Anda memasukkan " + n + " data"). int n = 0. System. String strbilangan = null. program berhenti").in)).println("Kesalahan IO.print("Masukkan bilangan pertama : "). System.public static void main(String[] args) { // TODO Auto-generated method stub double jumlah = 0. while (bilangan != 0) { jumlah += bilangan. rata-rata tidak bisa dihitung").out. } catch (IOException ioe) { System.out.parseDouble(strbilangan). n++.

operator ! membalik isi dari boolean. Dengan menuliskan while (!jawaban) berarti sama dengan menguji apakah jawaban berisi false. while diakhiri dengan tanda . Pernyataan do .. untuk memecahkan suatu masalah dengan perulangan do . while juga bisa diekspresikan dengan perintah while.Berikut hasil keluarannya : Pernyataan do . Contoh sederhana adalah program bermain game. Atau apabila perintah berbentuk blok kumpulan perintah-perintah. bisa diganti dengan while (!jawaban). while memberikan keleluasaan kepada Anda untuk berekspresi dengan lebih lugas. Jika suatu saat Anda harus menulis kondisi pada pernyataan while seperti ini while (jawaban == true). Anda bisa mengganti pernyataan ini menjadi while (jawaban). bisa dituliskan dalam bentuk perintah while (suatu_kondisi) perintah . di mana game akan menanyakan apakah user ingin bermain lagi.. do perintah while (suatu_kondisi). dengan bentuk.. di akhir while. Demikian juga dengan while (jawaban == false).. demikian juga sebaliknya.. misalnya dari true menjadi false atau sebaliknya. do { main game tanya user apakah ingin main lagi } while (user menjawab ya). Pengujian dilakukan di akhir setelah suatu kondisi didapat dalam eksekusi perulangan pertama kali. bisa juga ditulis dalam bentuk do { perintah-perintah } while (suatu_kondisi).. Perlu diingat bahwa pernyataan do . Dalam hal ini badan perulangan akan dieksekusi terlebih dahulu tanpa memperdulikan apakah suatu kondisi bernilai true atau false.. do perintah while (suatu_kondisi). while pada dasarnya merupakan pernyataan while terbalik. while Kadang-kadang akan lebih mudah menulis perulangan jika penguji perulangan dilakukan di akhir badan perulangan. Seperti dijelaskan pada bab tentang operator boolean. Menguji apakah jawaban sama dengan true sama artinya dengan melihat apakah jawaban berisi "true". Pernyataan do . Sebenarnya....

. Di tengah-tengah program. Pernyataan while atau do . Pernyataan break dan continue Pernyataan while dan do . kemudian memerintahkan program untuk keluar dari badan perulangan saat itu juga.. maka program akan keluar dari perulangan yang berada persis di atasnya.Demikian juga dengan while (suatu_kondisi) perintah bisa juga dituliskan dalam bentuk if (suatu_kondisi) { do { perintah while (suatu_kondisi). while dapat dibuat bertingkat. } tanpa merubah aliran program sama sekali. while. kita uji apakah suatu_kondisi bernilai false. . <code> Apa makna dari program di atas? <code>while (true) artinya memerintahkan program untuk melakukan perulangan selamanya.. Caranya dengan menggunakan perintah break<code>.. sehingga program seperti <code>while (suatu_kondisi) perintah bisa ditulis dalam bentuk while (true) perintah if (!suatu_kondisi) break. maka program akan keluar dari perulangan yang persis di atasnya.. Jika ya. Pengujian bisa juga dilakukan di tengah-tengah badan perulangan. maka perintah break akan dieksekusi yang menyebabkan program keluar dari badan perulangan ke perintah berikutnya di luar badan perulangan. Misalnya.. karena true tidak akan berubah. Perlu diingan juga apabila perintah break diberikan di dalam pernyataan if. apabila perintah break diberikan setelah perintah_lain maka program akan keluar dari dalam perulangan while (kondisi_lain). misalnya membuat blok while dalam blok while. tapi tentu saja ini tergantung dari cara pikir masing-masing programmer dan juga masalah yang akan dipecahkan. while (suatu_kondisi) { perintah while (kondisi_lain) { perintah_lain while (kondisi_lain_lagi) { perintah_baru } } } Apabila perintah break diberikan. while menguji kondisi di awal atau di akhir badan perulangan. Kadang-kadang gaya penulisan ini lebih masuk akal ketimbang gaya penulisan baku seperti while atau do .

i++. while (i <= 100) { jumlah += i. kemudian kembali kepada pernyataan while untuk mengevaluasi apakah suatu_kondisi bernilai true. artinya selama perulangan tersebut berjalan. Kita bisa ekspresikan program tersebut dalam bentuk i = 1. perintah_lagi perintah_lain_lagi } Perulangan akan menjalankan perintah. mengabaikan perintah hingga perulangan berakhir. perintah continue digunakan untuk menghentikan operasi saat itu. Tetapi tergantung dari permasalahan yang akan kita pecahkan.Selain perintah break yang secara langsung menghentikan perulangan.+100. while (suatu_kondisi) { perintah continue. kemudian kembali kepada perintah while lagi. mengabaikan perintah_lagi dan perintah_lain_lagi.. } Perulangan ini dapat ditulis juga dengan jumlah = 0. Jika ya perulangan akan diteruskan. Setiap bentuk perulangan for dapat diubah menjadi bentuk perulangan while dengan fungsi yang sama tanpa mengubah alur program. perintah_lagi dan perintah_lain_lagi tidak akan pernah dieksekusi. jumlah = 0. Perulangan for Kita akan membahas bentuk perulangan lain. kita akan menghitung 1+2+3+4+5+. Misalnya. menulis program dengan for akan membuat alur program lebih mudah dipahami. Misalnya. yaitu perulangan for. i <= 100. for (i = 1. i++) jumlah += i Apa point-point penting yang kita lihat dari perubahan ini? Pertama mari kita lihat bentuk penggunaan while yang umum dilakukan inisialisasi variabel while (suatu_kondisi_variabel) { . Tetapi karena ada perintah continue..

tidak berulang terus menerus.perintah update_variabel } Di sini perulangan while memiliki 3 komponen penting. ketiga komponen ini dirangkai menjadi satu dalam bentuk for (inisialisasi_variabel. yang artinya perulangan akan terus dieksekusi tanpa henti. kondisi_variabel. dan terakhir update_variabel. yaitu instruksi mengubah nilai kondisi variabel untuk membatasi perulangan sehingga akan selesai suatu saat. kondisi_variabel. Bentuk paling umum dari perulangan for adalah menghitung. dapat dituliskan juga dalam bentuk for (inisialisasi_variabel. kondisi_variabel harus berbentuk pernyataan boolean seperti suatu_kondisi pada pernyataan while. perintah break harus diberikan ditengah-tengah badan perulangan. Pada perulangan for. suatu_kondisi_variabel. Biasanya perulangan ini memiliki bentuk seperti for (variabel = nilai_minimum. update_variabel) { banyak_perintah } Di sini inisialisasi variabel bisa berupa apa saja yang berbentuk perintah. . kondisi_variabel. inisialisasi_variabel. update_variabel) perintah atau jika perintah merupakan blok yang terdiri dari banyak perintah. variabel++) { perintah } Perhatikan bagian terakhir adalah menaikkan nilai variabel dengan 1. Bagian yang tidak diisi yang selalu digantikan dengan true. dalam bentuk variabel = nilai_awal. misalnya memberikan variabel dengan nilai awal tertentu. atau update_variabel dapat dikosongkan dan tidak harus selalu diisi. yang artinya perulangan akan dimulai dengan nilai_minimum. Sedangkan update_variabel juga berbentuk perintah. variabel <= nilai_maksimum. Untuk menghentikannya. yaitu inisialisasi. yaitu memberikan nilai awal suatu variabel. diakhiri dengan nilai_maksimum dengan jeda 1. yaitu pengujian bahwa perulangan akan terus dilakukan selama kondisi ini bernilai true.

i <= 17.out.println(i).Contoh.out. } Catatan penting! Variabel yang akan digunakan. Java adalah bahasa pemrograman ketat. jika kita ingin berhitung 2.5. yang merupakan deklarasi variabel i dengan tipe data int sekaligus menginisialisasi nilainya dengan 1. Perulangan for bertingkat Seperti pada perulangan while. i--) { System.14. adalah variabel yang harus dideklarasikan sebelumnya. perulangan for pun dapat dilakukan bertingkat.out. artinya perulangan for di dalam perulangan for. Misalnya for (int i = 1.println(i). i++. kita bisa menggunakan perintah seperti for (i = 20. kita bisa mengekspresikan for dengan for (i = 2. atau dengan kata lain. kita bisa ekspresikan dengan for (i = 1. yang artinya semua harus didefinisikan dengan jelas sebelum digunakan. Untuk banyak kasus. Kita ambil contoh sederhana misalnya membuat tabel perkalian seperti 1 2 3 4 5 6 7 8 9 10 11 12 2 4 6 8 10 12 14 16 18 20 22 24 . } Untuk menghitung mundur.17. deklarasi variabel dan perulangannya bisa dilakukan serentak pada bagian inisialisasi variabel. i++) { System. i <= 10.println(i + " " + j). dalam contoh di atas i dan j.out. } Atau jika kita ingin menghitung maju dan mundur pada saat yang bersamaan. i <= 10. misalnya i dari 1 hingga 10 dan j dari 10 hingga 1. mulai dari 2 hingga 17 dengan jeda 3.println(i) } Perhatikan ada imbuhan int di depan inisialisasi variabel i.11.8. j = 10. j--) { System. i >= 0. i += 3) { System.

12 cetak perkalian i dengan 1..3.print(i*j + " "). j++) { System. sehingga algoritma di atas bisa kita tulis sebagai untuk setiap baris i = 1.. i++) { for (int j = 1..out.3.. .println(""). j <= 12...12 cetak baris baru Kalau kita jabarkan lebih lanjut.2. perintah kedua juga merupakan perulangan dari 1 hingga 12.3 6 9 12 15 18 21 24 27 30 33 36 4 8 12 16 20 24 28 32 36 40 44 48 5 10 15 20 25 30 35 40 45 50 55 60 6 12 18 24 30 36 42 48 54 60 66 72 7 14 21 28 35 42 49 56 63 70 77 84 8 16 24 32 40 48 56 64 72 80 88 96 9 18 27 36 45 54 63 72 81 90 99 108 10 20 30 40 50 60 70 80 90 100 110 120 11 22 33 44 55 66 77 88 99 110 121 132 12 24 36 48 60 72 84 96 108 120 132 144 Program untuk membuat tabel perkalian tersebut bisa diekspresikan dengan algoritma pseudocode sebagai berikut untuk setiap baris i = 1.12 untuk setiap kolom j = 1.2.out. } System....2.3.3.12 cetak i*j cetak baris baru Kita bisa terjemahkan ke dalam bahasa Java sebagai for (int i = 1.2. i <= 12..

j++) { System. i++) { for (int j = 1.println("").print(i*j + " ").googlecode. } } } . i <= 12.out.out.} Berikut ini adalah contoh program yang bisa diunduh dalam bentuk zip file atau dari gudang SVN di alamat http://belajarjava. } System. j <= 12. public class TabelPerkalian { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub for (int i = 1.com/svn/trunk/TabelPerkalian : package tabelperkalian.

Berikut ini hasil kelurannya: Pernyataan if Pernyataan if merupakan salah satu pernyataan percabangan pada Java. Ada beberapa hal menarik yang mungkin berguna. else System. dengan bentuk umum seperti if (suatu_kondisi) perintah1 else perintah2 Seperti biasa. . Bagian else yang terdiri dari kata "else" dan perintah2 tidak selalu harus ada.out. perintah1 dan perintah2 bisa berbentuk blok yang terdiri dari beberapa perintah.println("perintah2"). Ambil contoh dalam pernyataan berikut if (x > 0) if (y > 0) System. Perhatikan bahwa baik perintah1 dan perintah2 bisa merupakan pernyataan if itu sendiri.println("perintah1").out. Pernyataan if merupakan bentuk percabangan 2 arah.

else di program di atas akan dianggap bagian dari pernyataan jika y > 0. Untuk memperbaikinya. Jika x <= 0. Java akan menganggap else terkait dengan if terdekat.println("perintah2").println("perintah1"). Lebih menarik lagi. perhatikan kode berikut if (kondisi_pertama) perintah1 else if (kondisi_kedua) perintah2 else perintah3 Lagi-lagi karena Java tidak membedakan indentasi penulisan. padahal yang kita maksud adalah else jika x > 0. } else System.Pertama-tama. komputer tidak peduli bagaimana Anda memformat paragraf dan indentasi dari pernyataan if tersebut.out. kita tambahkan tanda kurung {} sehingga menjadi if (x > 0) { if (y > 0) System. else System.out.out. sedangkan kode kedua java akan mencetak "perintah2". pada kode pertama Java tidak mencetak apa-apa ke layar.out. Kedua pernyataan tersebut memiliki arti yang berbeda. maka kode tersebut akan diterjemahkan Java seperti . sehingga kode di atas akan dianggap seperti if (x > 0) if (y > 0) System.println("perintah1").println("perintah2").

Jika false. else if (suhu < 30) System.out. Jika false.println("Panas"). maka perintah1 dieksekusi sementara perintah2 dan perintah3 diabaikan. Berikut ini adalah contoh penggunaan percabangan 3 arah. atau perintah3. Jika true.if (kondisi_pertama) perintah1 else if (kondisi_kedua) perintah2 else perintah3 Dengan kata lain perintah tersebut lebih seperti percabangan 3 arah. misalnya if (kondisi_pertama) perintah1 else if (kondisi_kedua) perintah2 else if (kondisi_ketiga) perintah3 else if (kondisi_keempat) perintah4 .println("Lumayan"). perintah2. maka hanya perintah3 saja yang dieksekusi. Komputer akan mengevaluasi kondisi_pertama. jika true. if (suhu < 20) System.out.println("Dingin"). Komputer akan mengeksekusi hanya salah satu dari perintah1. else System.out. maka perintah2 akan dieksekusi dan perintah3 diabaikan. Kita bahkan dapat membentuk pernyataan if-else ini menjadi percabangan N arah. maka kondisi_kedua akan dievaluasi.

yaitu dengan pernyataan if (a < b && a <c) Jika a betul merupakan bilangan terkecil. maka urutannya adalah b. maka kita uji apakah b lebih kecil dari c dengan perintah if (b < c) Jika a bukan bilangan terkecil. Mula-mula kita cek apakah a lebih kecil dari b dan c. a. c.. Misalnya kita mempunyai 3 variabel a.println(a + " " + b + " " + c).out. Jika tidak. Sekarang mari kita rangkai logika untuk menentukan urutan bilangan dari kecil ke besar. . c. sehingga kita harus menguji lagi dengan if (a < c) Jika a lebih kecil dari c. maka kita bisa tentukan urutan bilangannya. bisa kita tuangkan dalam bentuk : if (a < b && a < c) { if (b < c) System. maka urutannya adalah b. Keseluruhan logika ini. salah satunya bisa merupakan bilangan terkecil. Kita hanya perlu membandingkan apakah b lebih kecil dari c dengan if (b < c) Jika b lebih kecil dari c. else if (kondisi_keNminus1) perintahNmin1 else perintahN Contoh berikut ini adalah mengurutkan 3 bilangan dari kecil ke besar. Demikian halnya apabila jika b > c. Tetapi kita belum tahu apakah bilangan terkecil berikutnya adalah a atau c. maka b atau c.b dan c. a. else . berarti kita tahu bahwa b adalah bilangan terkecil. Bilangan yang paling kecil adalah bilangan yang lebih kecil dari kedua bilangan yang lain. .

} Logika di atas bisa juga dituangkan dengan cara lain. kita tahu bahwa urutannya pasti a terlebih dahulu baru b. else System. Pertama kita cek apakah a < b.println(c + " " + a + " " + b). } else { if (c < b) System.println(c + " " + b + " " + a). Kemudian kita lihat apakah c berada di sebelah kiri a atau disebelah kanan b atau di tengah-tengah. Demikian seterusnya jika urutannya b terlebih dahulu baru a. Jika ya. else System. else if (c > b) System.out. } else if (b < c) { if (a < c) System.out.println(a + " " + c + " " + b).out.out.println(a + " " + b + " " + c).out. else System.System. else if (c > a) . Sehingga kodenya bisa dituliskan dalam bentuk : if (a < b) { if (c < a) System.println(c + " " + b + " " + a).out. } else { if (a < b) System.out.println(b + " " + a + " " + c).out.println(b + " " + c + " " + a).out. yaitu melihat urutannya.println(c + " " + a + " " + c).println(a + " " + c + " " + b).

default: perintah_lain } Di sini pernyataan switch akan mencari nilai ekspresi yang sesuai dengan nilai-nilai yang didaftarkan pada pernyataan case.System. Catatan ekspresi hanya bisa berbentuk nilai bilangan bulat (int. case nilai3: perintah3 break.println(b + " " + c + " " + a). maka program akan melompat ke cabang case tersebut dan melakukan perintah yang terdapat di sana. else System.out. . Jika salah satu nilai ditemui. case nilai2: perintah2 break. Pernyataan switch lebih jarang digunakan. short.println(b + " " + a + " " + c). tetapi sering bermanfaat apabila kita ingin menuliskan percabangan multi arah. dan sejenisnya) atau karakter. } Pernyataan switch Penyataan percabangan kedua yang dimiliki Java adalah switch. Pernyataan switch memiliki bentuk sebagai berikut switch (ekspresi) { case nilai1: perintah1 break. Jika tidak ditemui.out. sehingga kita tidak bisa menggunakan switch untuk mengevaluasi ekspresi yang berbentuk String. maka program akan melompat ke perintah yang terdapat pada pernyataan default.

} Salah satu aplikasi di mana pernyataan switch berguna adalah untuk memproses menu. 7. 4.out.Pernyataan break di atas sebetulnya tidak harus selalu ada. atau 5"). case 6: case 7: case 8: System. atau 8"). Menu memiliki beberapa pilihan dan user akan diminta untuk memilih suatu pilihan.out. perintah break di sini memerintahkan komputer agar segera keluar dari blok switch apabila perintah tersebut telah selesai dilaksanakan. 3. break.println("Angka tersebut bernilai 1").out. lihat kode berikut ini : switch (N) case 1: System.println("Angka tersebut bernilai 6. . Kita dapat menggunakan switch untuk menginstruksikan komputer untuk melakukan tugas tertentu sesuai dengan menu yang dipilih oleh user. default: System. Tetapi. Misalnya. Apabila perintah break tidak diberikan.8").println("Angka tersebut bernilai 2. maka program akan terus mengeksekusi perintah lain meskipun sudah berada di luar nilai yang tertera dalam pernyataan casenya. break.out. case 2: case 3: case 4: case 5: System.println("Angka tersebut tidak bernilai 1 . break.

out. i++). sehingga apabila Anda menulis kode seperti if (x > 0). Perintah System. Biasanya argumen yang diberikan berupa opsi bagaimana program harus dilaksanakan. Dalam Java. perintah1 maka perintah1 akan tetap dilaksanakan walaupun x <= 0." setelah for menyatakan bahwa program tidak melakukan apa-apa di dalam perulangan. Di sini ls atau tar adalah nama program dan "-l" atau "xfz blabla" adalah argumen yang diberikan pada saat program dijalankan. maka tidak asing untuk menemukan perintah pada Linux seperti "ls -l" atau "tar xfz blabla". Pernyataan kosong Pernyataan kosong sebenarnya merupakan blok kosong. Kenapa? Karena tanda ".out.println("hallo"). dan synchronized untuk mengatur kontrol untuk multi-threading. Misalnya perintah berikut for (i = 1. atau try. Beberapa kata kunci lain akan juga dibahas pada subjek tentang pemrograman berorientasi objek yang akan kita bahas kemudian. System. seperti return yang digunakan untuk membuat subrutin sendiri. tetapi pernyataan-pernyataan ini merupakan pernyataan lanjutan Java. i <= 10. Di sini pernyataan switch juga berguna untuk memilih bagaimana program akan berjalan.Jika Anda ingat pernyataan main() pada program Java... pernyataan main memiliki parameter String[] args.catch dan throw untuk mengontrol alur kesalahan apabila ditemui di tengah program (atau dengan kata lain eksepsi atau pengecualian). Pernyataan-pernyataan lain Hingga saat ini kita sudah membahas hampir semua pernyataan yang Java sediakan. atau sama dengan {} tanpa perintah apa-apa di dalamnya. Anda berharap untuk mencetak kata hallo 10x di layar. Jika Anda terbiasa atau pernah bergaul dengan Linux. sehingga perintah ini hanya dijalankan 1x saja. Contoh Program switch case . Ada beberapa yang akan kita bahas kemudian.println("hallo") tidak berada di dalam perulangan for. pada kenyataannya hanya 1 hallo yang dicetak. pernyataan kosong juga berarti tanda . Perintah kosong sering merupakan sumber kesalahan dan salah satu fitur yang sulit untuk dicari kesalahannya pada saat debugging. di mana args merupakan argumen yang diberikan pada saat program dijalankan melalui konsol.

komputer adalah pemain pertama. kemudian hasilnya siapa yang menang akan ditampilkan di layar. System. . public class MainSuit { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub // cetak aturan main dan input dari user System. dan 2 berarti Kelingking.println("Permainan suit"). Hanya 3 jari yang boleh dipakai: jempol. sedangkan user adalah pemain kedua. Dalam program ini. 1. dan Kelingking menang lawan Jempol. T untuk Telunjuk dan K untuk Kelingking. dan K akan diubah menjadi angka 0. J.io.out.println("=============="). Dalam permainan real. telunjuk.println("Masukkan salah satu dari 3 kemungkinan :"). dan 2 seperti pada komputer. Hasil perhitungan komputer dan hasil input dari user akan dibandingkan. import java. package mainsuit. User akan diberikan pertanyaan untuk memasukkan J untuk Jempol. Permainan ini terdiri dari dua pemain. 0 berarti Jempol.println("J untuk Jempol"). dan kelingking. Komputer akan menggunakan perintah random() untuk menghitung salah satu dari 3 pilihan.out.Kita akan membuat program untuk main suit.out. Telunjuk menang lawan Kelingking. 1 berarti Telunjuk. System. Peraturannya : Jempol menang lawan Telunjuk. Kemudian dengan pernyataan switch. System. T.*.out. biasanya dua pemain mengadu suit dengan saling menunjukkan jari.

println("").out. int suitKomputer = 0. System.println("Kesalahan IO.println("T untuk Telunjuk").in)). } // pastikan bahwa user memasukkan sesuatu dengan mengecek .exit(1). // Kita gunakan pernyataan while hingga user betul // memasukkan salah satu dari J. int suitUser = 0. } catch (IOException ioe) { System. System. System.out. atau K boolean inputvalid = false. T.System. // baris kosong // variabel untuk mengambil input dari user BufferedReader br = new BufferedReader(new InputStreamReader(System. jalankan perulangan ini while (!inputvalid) { System. program berhenti").out.println("K untuk Kelingking").out. // selama input tidak valid.print("Masukkan suit Anda "). try { input = br.out. String input = null.readLine().

inputvalid = true. inputvalid = true. // kita ganti inputvalid agar perulangan selesai break. case 'k' : case 'K' : suitUser = 2. // kita ganti inputvalid agar perulangan selesai break.charAt(0)) { case 'j' : case 'J' : suitUser = 0.// apakah panjang input > 0 // jika tidak. // kita ganti inputvalid agar perulangan selesai break. } } } // sekarang menghitung suit komputer // Math.random() menghasilkan nilai acak antara 0 dan 1 // jika kita kali 3. case 't' : case 'T' : suitUser = 1. inputvalid = true.length() > 0) { switch (input. maka perulangan akan dilanjutkan if (input. berarti menghasilkan nilai acak antara 0 dan 3 .

println("Suit komputer = Jempol"). // suatu saat "mungkin" nilai random bernilai 3 // karena 3 tidak ada dalam suit kita.0232323 menjadi 1 suitKomputer = (int)(Math. switch (suitUser) { // jika user Jempol case 0: System.random()*3).println("Seri").// perintah (int) untuk mengubah bilangan real menjadi bilangan bulat // dengan cara menghilangkan semua digit di belakang koma // misalnya 1. } // menghitung siapa yang menang switch (suitKomputer) { // jika komputer Jempol case 0: // cetak suit Komputer System. // jika user Telunjuk case 1: .out. yaitu 0. atau 2 // dalam hal ini kita ganti jadi 2 if (suitKomputer == 3) { suitKomputer = 2. 1. break.out. maka kita harus ubah menjadi // salah satu suit yang valid.

// jika user Telunjuk case 1: System. break. break.out.println("Anda menang").System.println("Anda kalah").println("Seri").out.println("Anda menang"). break.println("Anda kalah").out. switch (suitUser) { // jika user Jempol case 0: System. } . // jika user Kelingking case 2: System.println("Suit komputer = Telunjuk").out.out. // dari switch(suitKomputer) // jika komputer Telunjuk case 1: // cetak suit Komputer System. } break. // jika user Kelingking case 2: System. break.out. break.

out.out. } break. // jika user Kelingking case 2: System. // dari switch(suitKomputer) } } } .break. switch (suitUser) { // jika user Jempol case 0: System. // dari switch(suitKomputer) // jika komputer Kelingking case 2: // cetak suit Komputer System.out. break. break.println("Suit komputer = Kelingking").out.println("Anda kalah").println("Anda menang"). // jika user Telunjuk case 1: System. break.println("Seri").

Ketika komputer mengeksekusi program. subrutin bisa berbentuk statik atau non-statik. dan akan dijelaskan lebih lanjut pada bab berikutnya. program besar dapat dipecah menjadi bagianbagian kecil. Subrutin boleh digunakan berulang-ulang. setiap kali nama subrutin tersebut dipanggil. Dengan cara ini.com/svn/trunk/MainSuit Bab V . dari mana pun di dalam program. dan diberi nama. kita tidak perlu lagi memikirkan bagaimana komputer melakukan tugas hingga sedetail mungkin. Dengan cara ini. Dalam bagian ini hanya subrutin statik yang akan dijelaskan lebih lanjut. Seperti dijelaskan sebelumnya. sehingga bisa dipanggil suatu saat di bagian lain program. Kotak Hitam Subrutin terdiri dari beberapa instruksi yang melakukan suatu tugas tertentu. program akan melaksanakan semua perintah di dalam subrutin tersebut. bahkan dari dalam subrutin lain. Subrutin non-statik adalah inti dari pemrograman berorientasi objek.googlecode.Berikut ini adalah contoh keluaran program Listing program di atas dapat Anda unduh melalui zip file atau pada gudang SVN di alamat http://belajarjava. Kumpulan instruksi ini bisa berupa suatu "tugas" yang cukup kompleks yang disatukan sebagai konsep. Kita hanya ingin tahu . Subrutin terdiri dari sekelompok perintah yang melakukan suatu tugas tertentu. Kita hanya perlu memanggil nama subrutin tersebut untuk menjalankan suatu "tugas". yang masing-masing melakukan perintah sederhana. Subrutin sering juga disebut dengan kotak hitam (atau black box) karena kita tidak perlu (atau tidak mau tahu) secara detail apa yang subrutin tersebut lakukan. Dengan cara ini kita bisa membuat subrutin sederhana yang digunakan berulangulang di seluruh program.Subrutin Pemrograman kompleks Salah satu cara yang digunakan untuk memecah permasalahan kompleks menjadi permasalahan yang lebih kecil adalah dengan subrutin. dikumpulkan dalam satu himpunan. Subrutin memiliki nama.

Atau dengan kata lain. Seperti halnya dengan program. ada keyboard yang bisa kita ketik. Tidak cukup untuk menyebutkan bahwa TV membutuhkan colokan kabel. kita bisa mengubah implementasi suatu subrutin. atau mungkin ada jendela untuk memberi dan mengambil informasi dari dalamnya. kita tidak perlu mengetahui tentang implementasi. handphone. kulkas. dan tanpa mengubah perilaku fungsi lain yang memanggil subrutin tersebut. Orang yang membuat kotak hitam ini tidak perlu mengerti bagaimana kotaknya akan digunakan. dan sebagainya. Dengan kata lain. Aturan kedua dari suatu kotak hitam adalah : Untuk menggunakan kotak hitam. dan perilakunya terhadap input yang diterimanya. Di kotak itu mungkin ada tombol yang bisa kita tekan. Misalnya dulu TV menggunakan tabung hampa. Tentunya untuk membuat kotak hitam. Sama halnya dengan AC. tetapi harus disebutkan bahwa colokan kabel digunakan untuk menyambung aliran listrik ke TV supaya TV bisa dinyalakan. MP3 player. mengganti channel. yaitu bagian luar. Hubungan ini disebut antar muka (interface). ada beberapa prinsip penting dari suatu kotak hitam : Antar muka harus sederhana. Karena kita bermaksud untuk menyembunyikan kompleksitas (dalam hal ini program yang akan kita buat). misalnya TV. tetapi sekarang menggunakan transistor.hubungan kotak hitam tersebut dengan dunia luar. Pembuatnya hanya menjamin bahwa kotak yang dibuat harus bekerja sesuai dengan yang diharapkan. tak berbelit-belit. untuk apa ia digunakan. menaikkan dan menurunkan volume dengan mudah tanpa harus mengetahui bagaimana TV bekerja. AC. Tetapi perubahan implementasi (dari tabung hampa ke transistor) tidak mengubah bagaimana TV dioperasikan dan apa yang kita lihat di TV. Pada akhirnya. . Anda cukup menekan tombol. kotak hitam membagi dunia menjadi 2 bagian. tanpa mengubah perilaku program secara keseluruhan. misalnya mengoptimasi subrutin tersebut agar lebih cepat. Antar muka bisa juga berupa spesifikasi yang menjelaskan apa yang dilakukan kotak hitam tersebut. Aturan ketiga dari kotak hitam : Pembuat (implementor) kotak hitam tidak perlu tahu bagaimana kotak hitam itu akan digunakan. Sekarang mari kita lihat bagian dalam dari kotak hitam. kita perlu mengetahui detail tentang implementasinya. Bagaimana AC atau TV bekerja disebut dengan implementasi. yaitu detail bagaimana ia bekerja. Antar muka kotak hitam tidak melulu harus berupa koneksi fisik antara kotak hitam dengan dunia luar. Apa contoh kotak hitam di sekitar kita? Sebetulnya banyak. Sebetulnya kita bisa mengganti implementasi selama apa yang dihasilkan dan apa yang diminta tetap sama. Kita bisa menyalakan TV. perilakunya tidak berubah. Kotak hitam digunakan untuk membantu baik si pembuat kotak hitam maupun penggunanya. kotak hitam tersebut akan digunakan dalam bermacam-macam situasi. Yang kita butuh adalah antar muka. dan bagian dalam. DVD player. jelas. menaikkan dan menurunkan temperatur tanpa harus mengerti bagaimana AC bekerja. dan mudah dimengerti.

karena dalam bahasa pemrograman lain. komentar yang kita tulis untuk menjelaskan subrutin itu harus memuat kontrak subrutin tersebut. Ketika kita menulis subrutin. seperti yang dibahas sebelum pada penjelasan tentang kotak hitam. Kedua bagian dari subrutin tersebut bisa disebut sebagai kontrak subrutin. Kadang kala kontrak ini seringkali tidak dituliskan dengan benar. Bagian sintaks dari subrutin mengandung penjelasan tentang apa yang harus diketik untuk memanggil subrutin tersebut.Dalam bahasa pemrograman. Untuk menulis program yang benar. Hal ini mungkin membuat Java sedikit tidak normal. Subrutin yang dideklarasikan di dalam kelas disebut dengan metode (method). Dan ini tidak mudah apabila subrutin dan variabel berada di luar kelas. terutama apabila beberapa paket harus digabungkan menjadi satu seperti dalam program kompleks. . Untuk mengerti dan bisa menggunakan subrutin tersebut seefektif mungkin. Kontrak subrutin bisa dijelaskan seperti "Ini yang harus Anda lakukan untuk menggunakan saya. yaitu subrutin main(). tetapi bab ini kita akan menggunakan subrutin dalam artiannya sebagai subrutin statik. kita harus mengetahui spesifikasi semantiknya. dan bukan bagian dari kelas itu sendiri. Dan bagian semantik menjelaskan bagaimana secara khusus apa yang akan dikerjakan oleh subrutin tersebut. Metode akan digunakan untuk subrutin nonstatik yang lebih merupakan sifat dari objek. dan ini yang akan saya lakukan untuk Anda". Paling tidak kita sudah kenal bagaimana subrutin didefinisikan. sehingga programmer yang menggunakannya harus menerka apa yang akan dilakukan. subrutin bisa diletakkan di mana saja termasuk di luar kelas. Perintah ini merupakan badan atau implementasi suatu subrutin. Salah satu dari fungsi kelas adalah menggabungkan subrutin dan variabel bersama. perintah yang terdapat di antara { dan } disebut juga badan subrutin. kita harus mengetahui spesifikasi sintaks dari subrutin tersebut. Subrutin Statik dan Variabel Statik Setiap subrutin yang dideklarasikan dalam Java harus dideklarasikan di dalam suatu Kelas (Class). Akan terdapat banyak kebingungan yang mungkin diakibatkan dari nama subrutin atau nama variabel yang sama. antar muka dari suatu subrutin harus terdiri dari komponen sintaks dan semantik. Tentu saja ini tidak efisien dan menghabiskan banyak waktu apabila kita harus menerka semua subrutin yang terdapat dalam bahasa pemrograman. Di bab kemudian kita akan menggunakan istilah metode. Definisi subrutin dalam bahasa pemrograman Java dapat dituliskan dalam bentuk sifat tipe_keluaran nama_subrutin ( daftar parameter ) { perintah } Kita sudah pernah mendefinisikan suatu subrutin. Perintah ini merupakan instruksi yang akan dieksekusi oleh komputer pada saat subrutin ini dipanggil.

Beberapa sifat yang pernah kita lihat adalah static dan public.sifat adalah sifat dari subrutin itu sendiri. Pertanyaan yang akan muncul adalah ganti channel ke mana? Dalam hal ini parameter dapat digunakan. misalnya dengan gantiChannel(17). Akhirnya kita sampai pada daftar parameter. double y dan bukan double x. atau bisa berisi lebih dari satu parameter dalam bentuk tipe_data nama_parameter Jika ada lebih dari satu parameter. Berikut ini adalah beberapa contoh deklarasi subrutin yang umum dilakukan : public static void mainGame() { // "public" dan "static" ada sifat.. y. Jika kita akan membuat fungsi. Kita akan membahas lebih lanjut tentang keluaran pada bagian berikutnya. Akan tetapi channel belum memiliki nilai. Nilainya akan diberikan pada saat subrutin ini dipanggil. maka tipe_keluaran adalah tipe data dari keluaran yang dihasilkan oleh fungsi tersebut. "void" adalah tipe_keluaran // "mainGame" adalah nama subrutin // daftar parameternya kosong . Daftar parameter dari suatu subrutin bisa juga kosong. Parameter akan dijelaskan lebih lanjut pada bagian berikutnya. misalnya channel berbentuk bilangan bulat (int) dan deklarasi subrutin gantiChannel dapat berbentuk seperti public void gantiChannel(int channel) { . Catatan bahwa masing-masing parameter harus terdiri dari satu tipe data dan satu nama. untuk digunakan dalam eksekusi subrutin tersebut. maka parameter-perameter tersebut dihubungkan dengan koma. yaitu subrutin yang menghitung suatu nilai kemudian mengembalikan hasilnya.. misalnya double x. Jika subrutin kita bukan fungsi dan tidak menghasilkan nilai apa-apa. } Pernyataan tersebut berarti subrutin gantiChannel() memiliki parameter channel yang bertipe int. Ada lebih dari selusin sifat yang bisa diberikan kepada subrutin. Kasus sederhana misalnya televisi memiliki subrutin gantiChannel(). Parameter adalah informasi yang diberikan kepada suatu subrutin dari dunia luar. kita gunakan tipe data spesial yang dinamakan void untuk menunjukkan bahwa tidak ada nilai keluaran yang akan dikembalikan oleh subrutin tersebut. Parameter adalah bagian dari antar muka suatu subrutin.

Sifat lain yang berkaitan dengan penentu akses adalah "protected" dan ini akan dibahas lebih lanjut pada bagian tentang pemrograman berorientasi objek. yaitu x yang bertipe data double // dan y yang juga bertipe data double . Ingatkah bahwa subrutin main() yang biasa kita gunakan dalam contoh-contoh program memiliki bentuk seperti berikut ? public static main(String[] args) { .. Jika tidak disebutkan jenis aksesnya dalam suatu definisi subrutin. maka otomatis subrutin itu memiliki sifat "package" yang artinya hanya bisa dipanggil dari paket yang sama dari kelas di mana ia didefinisikan.. // perintah untuk mengambil N data ditulis di bagian ini } static boolean kurangDari(double x. "int" adalah tipe_keluaran // "ambilNdata" adalah nama subrutin // dan parameternya adalah N yang memiliki tipe data int .. // perintah untuk memainkan game ditulis di bagian ini } int ambilNdata(int N) { // tidak ada sifat.. Sifat "public" dan "private" dinamakan penentu akses (access specifier). termasuk dari luar kelas yang dimaksud.... Subrutin pertama memiliki sifat "public" yang artinya subrutin ini dapat dipanggil dari bagian manapun. double y) { // "static" adalah sifat. "boolean" adalah tipe_keluaran // "kurangDari" adalah nama subrutin // parameternya ada 2... Ada lagi sifat subrutin yaitu "private" yang berarti hanya bisa dipanggil dari dalam kelas di mana subrutin tersebut didefinisikan. dan subrutin ini tidak dibahas dalam bagian ini. // perintah untuk menguji apakah x lebih kecil dari y ditulis di sini } Dalam contoh kedua perhatikan bahwa sifatnya tidak "static".. } .

mainGame() dideklarasikan dalam kelas Gundu. pada dasarnya kita memberitahu Java bahwa suatu subrutin tersedia dalam suatu kelas. maka subrutin ini dapat juga dipanggil dari luar kelas di mana ia dideklarasikan.mainGame(). Kita akan bahas tentang array pada bagian struktur data di bab berikutnya. Untuk membedakannya variabel yang didefinisikan di dalam kelas disebut variabel anggota. maka parameter bisa dihilangkan. (Hal ini juga berlaku untuk kelas main(). bukan Catur.nama_subrutin(parameter).Sifatnya adalah "public" dan "static". Menjalankan subrutin Ketika kita mendefinisikan subrutin. meskipun kita tinggal memanggilnya secara spesifik. tetapi tanda kurungnya () harus tetap ada meskipun kosong. Apabila subrutin tersebut tidak bersifat "statik" maka nama_kelas harus diganti dengan nama objek jelmaan kelas tersebut. meskipun dari dalam subrutin yang berbeda. untuk memanggil suatu subrutin dapat dilakukan dengan bentuk nama_subrutin(parameter). Dan ini juga membedakan bahwa yang dimainkan adalah Gundu. bisa dilakukan dalam bentuk nama_kelas. Misalnya. Juga. apabila subrutin tersebut memiliki sifat "static". Variabel juga bisa didefinisikan di dalam subrutin. Lebih umum. misalnya dari dalam subrutin main(). misalnya variabel. Subrutin tersebut tidak dijalankan sampai ia dipanggil. . (Akan dijelaskan lebih jauh nanti pada bab tentang pemrograman berorientasi objek).) Misalnya subrutin mainGame() di atas dapat dipanggil seperti mainGame(). Pernyataan ini dapat dipanggil di mana pun dalam kelas yang sama. maka mainGame dapat dipanggil dari kelas lain seperti Gundu. karena variabel tersebut adalah anggota kelas. Variabel Statik Suatu kelas juga bisa berisi lain hal selain subrutin. tetapi sistem operasi kita akan memanggil subrutin main() pada saat program tersebut dijalankan. yang disebut variabel lokal. namanya adalah "main" dan parameternya adalah args yang bertipe data array dari String.mainGame() atau UlarTangga. Penggunaan nama kelas di sini berarti memberitahu Java di mana subrutin mainGame() harus dicari (dalam hal ini di dalam kelas Gundu). Karena mainGame() bersifat "public". Dan untuk memanggil subrutin dari luar kelas. apabila tidak ada parameter yang didefinisikan.mainGame().

Variabel anggota statik dimiliki oleh kelas. "public". Caranya "File -> New -> Java Project" kemudian masukkan RataRata2. Misalnya. variabel statik digunakan bersama oleh seluruh bagian kelas. Ketika kita mendeklarasikan suatu variabel di dalam subrutin. misalnya "static". Deklarasi variabel anggota dapat dilakukan dengan cara yang sama seperti deklarasi variabel dalam subrutin. Java otomatis memberi nilai awal. Sekarang kita akan pisahkan kode untuk mengambil input dari user dalam kelas yang dinamakan KonsolInput. mereka juga bisa diberi attribut yang berisi sifatnya. Atau dengan kata lain. . sedangkan variabel "public" dapat diakses dari manapun. dan akan selalu ada selama kelas tersebut ada. while. Seperti halnya penentu akses pada subrutin. static private double x. sehingga bisa kita panggil dari luar dengan System. Kecuali.. Akan tetapi untuk variabel anggota. Misalnya int akan diberi nilai awal 0.Mengubah Program RataRata Kita mulai dengan program RataRata yang kita bahasa pada bagian tentang while dan do . tidak peduli dari bagian program mana perubahan variabel ini dilakukan. Perhatikan bahwa di dalam program tersebut kita harus menulis berulang-ulang untuk mendapatkan input data dari user. memiliki variabel out. Pertama-tama buat project baru di Eclipse yang dinamakan RataRata2. atau "private". Misalnya. Contoh Subrutin . Variabel lokal hanya bisa dipanggil dari dalam subrutin di mana ia dideklarasikan. Komputer akan menyiapkan memori tempat penyimpanan variabel statik pada saat Java interpreter dijalankan. kita harus memberi nilai awal untuk variabel tersebut.. variabel juga bisa bersifat statik atau non-statik. static int umur. kelas System.out. tidak peduli bagian program mana yang memanggilnya. Kapanpun variabel ini dipanggil. variabel yang bersifat "private" hanya bisa diakses dari dalam kelas yang bersangkutan. dan String diberi nilai awal null. sehingga tidak perlu diinisialisasi terlebih dahulu. Ini berarti variabel statik bisa diisi dari subrutin satu dan dimodifikasi dari subrutin lainnya. karakter diberi nilai yang berupa karakter dengan nilai Unicode 0. Caranya misalnya dengan memberi nilai di awal subrutin main(). Di bagian ini kita hanya akan membahas variabel statik. sementara boolean diberi nilai awal false. Perubahan variabel statik ini akan mengubah isi memori tersebut. Kita tentu saja bisa memberi nilai awal apabila nilai awal yang diberi Java tidak cocok dengan aplikasi kita.Seperti subrutin. ia akan mengambil data dari memori di mana dia disimpan.

. "double" merupakan tipe data keluarannya karena kita ingin subrutin ini mengembalikan input bertipe double sehingga siap untuk digunakan. . "File -> New -> Class". Kita bisa definisikan subrutin ini dengan public static double ambilDouble(String pertanyaan) { .. masukkan package ratarata2 dan Name KonsolInput seperti gambar berikut : Kita akan membuat subrutin statik yang dinamakan ambilDouble() yang tugasnya memberi pertanyaan kepada user. "ambilDouble" adalah nama subrutin ini. } "public" dan "static" adalah sifat subrutin ini. mengambil input dari user dan mengubah input dari user menjadi bilangan real (tipe data double).Kemudian buat kelas baru yang dinamakan KonsolInput. dan "String pertanyaan" adalah parameternya yaitu berupa pertanyaan yang diberikan kepada user pada saat data akan diambil.

kita ganti dengan System. yang berarti kembalikan bilangan kepada si pemanggil fungsi ini. } // mengubah input menjadi double agar bisa diproses lebih lanjut bilangan = Double. try { strbilangan = br. Jangan lupa juga untuk menambahkan import java. Sekarang subrutin ambilDouble() menjadi seperti ini package ratarata2.print("Masukkan bilangan pertama : "). .io. Kita akan kembalikan "bilangan" kepada si pemanggil. di awal kelas karena BufferedReader adalah anggota dari paket ini.out. sehingga baris System.exit(1). BufferedReader br = new BufferedReader(new InputStreamReader(System.out.Apa yang harus dilakukan sekarang? Kita ambil perintah untuk mengambil data dari RataRata yaitu : double bilangan = 0. System. } catch (IOException ioe) { System.*.in)).out. String strbilangan = null.println("Kesalahan IO. program berhenti"). sehingga di akhir subrutin kita beri perintah return bilangan. System.print(pertanyaan).out.parseDouble(strbilangan).print("Masukkan bilangan pertama : ").readLine(). Ingat bahwa parameter "String pertanyaan" adalah pertanyaan yang akan kita ajukan kepada user.

import java. try { strbilangan = br.print(pertanyaan).out. public class KonsolInput { public static double ambilDouble(String pertanyaan) { String strbilangan = null.println("Kesalahan IO. } } .parseDouble(strbilangan). System. program berhenti").readLine().exit(1).out.*. double bilangan.io. } bilangan = Double. System. return bilangan. } catch (IOException ioe) { System.in)). BufferedReader br = new BufferedReader(new InputStreamReader(System.

seperti pada gambar berikut : Dengan menggunakan subrutin yang baru kita buat. kita modifikasi program RataRata menjadi RataRata2 sebagai berikut : package ratarata2. public class RataRata2 { /** * @param args .Kemudian kita buat kelas baru yang dinamakan RataRata2.

out.ambilDouble("Masukkan bilangan berikutnya (atau 0 untuk mengakhiri) : "). int n = 0.println("Data kosong. } // hitung rata-rata double ratarata = jumlah/n. rata-rata tidak bisa dihitung"). while (bilangan != 0) { jumlah += bilangan.println("Rata-rata bilangan yang dimasukkan adalah " + ratarata).ambilDouble("Masukkan bilangan pertama : "). n++.out. // cetak hasilnya ke layar if (n == 0) { System.println("Anda memasukkan " + n + " data"). bilangan = KonsolInput. System. } . double bilangan = 0.out. // sama dengan : jumlah = jumlah + bilangan // sama dengan : n = n+1 bilangan = KonsolInput. } else { System.*/ public static void main(String[] args) { // TODO Auto-generated method stub double jumlah = 0.

Jempol dilambangkan dengan 0. kita panggil subrutin ambilDouble() dengan perintah bilangan = KonsolInput. kita gunakan pernyataan switch case. Telunjuk dilambangkan dengan 1. Hasil keluarannya sama dengan pada kelas RataRata Program di atas dapat diunduh dalam bentuk zip file atau melalui gudang SVN di alamat : http://belajarjava. Cara lain untuk menentukan pemenangnya adalah dengan mengurangi suitKomputer dan suitUser . Dalam program sebelumnya.com/svn/trunk/RataRata2 Contoh Program Subrutin dan Variabel Statik Mari kita lihat kembali dan kita akan ubah program MainSuit pada halaman ini. yaitu kita tuliskan semua kemungkinan dalam permainan.googlecode. dan Kelingking dilambangkan dengan 2.ambilDouble("Masukkan bilangan berikutnya (atau 0 untuk mengakhiri) : "). Pertama-tama kita akan ubah algoritma untuk menentukan siapa yang menang. Di kelas RataRata2. Pertama. dan bilangan = KonsolInput.ambilDouble("Masukkan bilangan pertama : ").} } Perhatikan beberapa perubahan di dalam program ini. Jika Anda ingat. di mana parameternya adalah pertanyaan yang diberikan kepada user sebelum memasukkan data. kita hapus perintah-perintah untuk mengambil input dari user karena sudah kita implementasikan pada subrutin ambilDouble() di kelas KonsolInput.

Apabila delta = 0. maka user menang. break.out.suitUser. Dengan sifat seperti di atas. System. System.delta = suitKomputer . Dalam hal ini delta -2. kita bisa ubah pernyataan switch case pada program sebelumnya dengan // menghitung siapa yang menang int delta = suitKomputer . dan ini berarti komputer menang. case -1: case 2: komputerMenang++. Sekarang coba masukkan apabila komputer 0 (Jempol) dan user 1 (Telunjuk).println("Hasilnya : Anda kalah"). Dalam hal ini delta bernilai -1. System. Dengan kata lain.out.println("Hasilnya : Anda menang"). maka permainan berakhir seri.out.println("Hasilnya : Seri").suitUser. switch (delta) { case 0: seri++. Coba lagi juga komputer 0 (Jempol) dan user 2 (Kelingking). dan ini berarti user menang sesuai dengan aturan bahwa Kelingking menang melawan Jempol. dan apabila delta bernilai 1. } . break. case 1: case -2: userMenang++. apabila delta bernilai -1 maka komputer menang. break.

Kita namakan subrutin ini mainGame(). kita tambahkan lagi variabel statik yang fungsinya digunakan untuk mendata berapa kali komputer menang. public static int seri = 0.in)). Kodenya sebagai berikut : public static int userMenang = 0. // selama input tidak valid. . // Kita gunakan pernyataan while hingga user betul // memasukkan salah satu dari J. berapa kali Anda menang dan berapa kali seri. public static void mainGame() { BufferedReader br = new BufferedReader(new InputStreamReader(System.print("Masukkan suit Anda ").out. int suitKomputer = 0. atau K boolean inputvalid = false. int suitUser = 0. public static int userMenang = 0. jalankan perulangan ini while (!inputvalid) { System. Kemudian kita akan pindahkan sebagian kode pada subrutin main sehingga dapat dipanggil berkali-kali tanpa harus menulis seluruh kode lagi.Kemudian. public static int komputerMenang = 0. T. // variabel untuk mengambil input dari user String input = null. public static int seri = 0. public static int komputerMenang = 0.

length() > 0) { switch (input. } catch (IOException ioe) { System.readLine().try { input = br.println("Kesalahan IO. // kita ganti inputvalid agar perulangan selesai break.charAt(0)) { case 'j' : case 'J' : suitUser = 0. case 'k' : case 'K' : suitUser = 2.out. program berhenti"). maka perulangan akan dilanjutkan if (input. inputvalid = true. // kita ganti inputvalid agar perulangan selesai . } // pastikan bahwa user memasukkan sesuatu dengan mengecek // apakah panjang input > 0 // jika tidak.exit(1). inputvalid = true. // kita ganti inputvalid agar perulangan selesai break. System. case 't' : case 'T' : suitUser = 1. inputvalid = true.

switch (delta) { case 0: .break.suitUser.0232323 menjadi 1 suitKomputer = (int)(Math. 1. yaitu 0. berarti menghasilkan nilai acak antara 0 dan 3 // perintah (int) untuk mengubah bilangan real menjadi bilangan bulat // dengan cara menghilangkan semua digit di belakang koma // misalnya 1. maka kita harus ubah menjadi // salah satu suit yang valid. atau 2 // dalam hal ini kita ganti jadi 2 if (suitKomputer == 3) { suitKomputer = 2. } // menghitung siapa yang menang int delta = suitKomputer .random() menghasilkan nilai acak antara 0 dan 1 // jika kita kali 3.random()*3). } } } // sekarang menghitung suit komputer // Math. // suatu saat "mungkin" nilai random bernilai 3 // karena 3 tidak ada dalam suit kita.

out. break.out. sehingga komputer akan menanyakan Anda untuk main lagi atau tidak. System. maka permainan akan diteruskan. break.out. System.seri++. System. dan statistik menang-kalah-seri akan ditampilkan.println("Hasilnya : Anda menang").println("J untuk Jempol"). Jika jawabannya ya.println("Hasilnya : Seri"). System. case 1: case -2: userMenang++.out.println("Hasilnya : Anda kalah").println("T untuk Telunjuk"). System.println("Masukkan salah satu dari 3 kemungkinan :"). public static void main(String[] args) { // TODO Auto-generated method stub // cetak aturan main dan input dari user System.out. } } Sekarang kita ubah subrutin main()-nya. System. Jika tidak. . break.println("==============").out. case -1: case 2: komputerMenang++. System. hanya tampilkan statistiknya saja. kemudian program akan keluar.println("Permainan suit").out.out.

// baris kosong while (true) { mainGame(). // tampilkan statistik System. String input = null. program berhenti").out. System.charAt(0) == 't') || (input.System.in)).exit(1).print("Main lagi (Y/T) ? ").out. System. System. // baris kosong Anda = " + userMenang + " // variabel untuk mengambil input dari user BufferedReader br = new BufferedReader(new InputStreamReader(System.println("").println("Statistik :").println("Kesalahan IO.out.out.println("Komputer = " + komputerMenang + " Seri = " + seri). System.out. System. try { input = br. } catch (IOException ioe) { System. .readLine(). } // keluar jika jawabannya tidak if ((input.println("K untuk Kelingking").println("").out.charAt(0) == 'T')) break.out.

. maka parameter merupakan alat atau mekanisme untuk memberikan informasi dari dunia luar ke dalam kotak. kita dapat mengatur perilaku suatu subrutin sesuai dengan input yang diberikan. Parameter merupakan bagian dari antar muka dengan suatu subrutin.googlecode.com/svn/trunk/MainSuitSubrutin> Parameter Jika subrutin adalah kotak hitam. Dengan menggunakan parameter.} } Berikut ini hasil keluarannya Dan program tersebut dapat Anda unduh dalam bentuk zip file atau melalui gudang SVN di alamat : http://belajarjava.

double bilangan. kemudian subrutin ambilDouble panggil dengan perintah ambilDouble(str).. suatu nilai harus ikut disertakan. Misalnya. AC memiliki parameter. Ketika komputer menjalankan perintah ini. maka isi dari str akan dikopi ke . yaitu mengatur suhu ruangan. AC akan selalu melakukan tugas yang sama. } catch (IOException ioe) { System.out. } bilangan = Double. Jika parameter yang diberikan berupa variabel. kita ambil contoh AC -.in)). } Di sini subrutin ambilDouble memiliki parameter tunggal yang bertipe String dan bernama pertanyaan. dan nilai ini dimasukkan dalam parameter "pertanyaan".out.print(pertanyaan). kemudian subrutin ambilDouble menjalankan semua perintah di dalamnya. misalnya variabel str berisi "kabar".readLine().yaitu alat yang mengatur suhu ruangan pada temperatur konstan. BufferedReader br = new BufferedReader(new InputStreamReader(System. tugas persis yang dilakukan tergantung suhu yang diterima dari remote control. public static double ambilDouble(String pertanyaan) { String strbilangan = null.parseDouble(strbilangan).exit(1). Kita ambil contoh pada kelas KonsolInput pada bagian terdahulu. program berhenti"). komputer akan memasukkan "hallo" ke dalam parameter "pertanyaan".println("Kesalahan IO. System.Sebagai analogi. try { strbilangan = br. subrutin dapat dipanggil dengan a = ambilDouble("hallo"). Akan tetapi. System. Ketika subrutin ini dipanggil. return bilangan. yaitu tombol remote yang digunakan untuk memasukkan suhu yang diinginkan.

Parameter aktual bersifat seperti nilai atau angka. double d. Perlu dicatat bahwa istilah "parameter" digunakan dalam dua konsep berbeda tetapi berkaitan. jadi bisa berbentuk ekspresi atau perintah apapun yang menghasilkan nilai atau angka. Yang pertama adalah "parameter" digunakan untuk mendefinisikan suatu subrutin.. double d.random() * 3. atau String.. boolean b) { . // perintah lainnya di sini } Subrutin ini bisa saja dipanggil dengan instruksi berikut. boolean b. // perintah lainnya di sini } . dan bersifat seperti halnya variabel dan memiliki tipe -.misalnya int. double.. kita harus memberi parameter aktual untuk setiap parameter formal yang didefinisikan. dan hasilnya akan dimasukkan ke dalam parameter formal. N = 1. parameter aktual akan dievaluasi. Parameter formal berbentuk seperti pengenal atau nama. Ketika komputer mengevaluasi subrutin ini. lihat contoh berikut. d = Math. . Math. pada dasarnya sama dengan menglakukan perintah-perintah berikut. "Parameter" yang digunakan untuk memanggil suatu subrutin disebut parameter aktual. static void lakukanSesuatu(int N.. lakukanSesuatu(1. Misalnya.random() * 3. x == 3). Sewaktu kita memanggil subrutin. Ketika suatu subrutin dipanggil. { int N. Parameter yang digunakan pada definisi suatu subrutin disebut parameter formal.dalam parameter "pertanyaan" terlebih dahulu sebelum seluruh perintah dalam subrutin ambilDouble dilaksanakan. b = (x == 3).

. } boolean ambil(String s) { .. Dua atau lebih subrutin dengan nama sama dalam suatu kelas tetapi memiliki tipe keluaran yang berbeda tidak diperbolehkan dalam Java. int ambil(String s) { .. } void taruh(boolean b) { .. dan parameter formal. Parameter digunakan untuk berhubungan dengan dunia luar sebagai alat untuk menerima nilai atau angka dari dunia luar... } double ambil(String s) { . Misalnya. Java agak sedikit berbeda karena memungkinkan dua atau lebih subrutin yang berbeda dalam kelas yang sama memiliki tanda subrutin yang berbeda. Perhatikan bahwa tanda subrutin tidak memiliki nama parameter. Variabel ini terlihat . void taruh(String s) { .. kalau kita coba definisikan 2 fungsi seperti berikut. yang didefinisikan pada definisi subrutin di dalam suatu kelas. variabel statik. sebetulnya jika kita hanya ingin menggunakan subrutin tersebut. Hal yang sama sekali berbeda akan terjadi apabila suatu subrutin menggunakan variabel yang didefinisikan di luar subrutin itu. Eclipse akan membantu kita untuk melihat parameter apa saja yang dibutuhkan. yang didefinisikan di dalam suatu blok. hingga saat ini kita sudah mengenal 3 jenis variabel: variabel lokal. Variabel lokal tidak memiliki hubungan dengan dunia luar sama sekali. } Terakhir. yang didefinisikan di dalam suatu kelas. berapa banyak parameter formal yang dimilikinya.boolean). Perubahan nilai pada variabel lokal dan parameter tidak mempengaruhi variabel itu sendiri karena sifatnya terisolasi. termasuk juga dapat menunjukkan apakah suatu subrutin dibebanlebihkan. Jika kita coba ketik System. maka Java akan memberi pernyataan kesalahan sintaks. dan tipe dari parameter formal tersebut.out.Untuk memanggil subrutin.. } void taruh(int i) { .. Infomasi ini disebut juga tanda subrutin. nama parameter tidaklah penting. yang kita perlukan adalah nama. (Mirip seperti bahasa C++) Subrutin yang seperti ini disebut subrutin yang dibebanlebihkan (overloaded).. } Kita sudah menggunakan subrutin yang dibebanlebihkan ini misalnya pada System. Variabel ini disebut variabel global. karena nama bukan merupakan bagian dari antar muka subrutin. Variabel tersebut hidup secara terpisah dari subrutin.. Tanda subrutin lakukanSesuatu dapat ditulis sebagai lakukanSesuatu(int.double. Misalnya.. dan bisa diakses oleh apapun di luar subrutin itu.println pada Eclipse.println().out.. } void taruh(double d) { .. Catatan : Overload tidak berlaku pada tipe keluaran subrutin.

sebagai berikut : static double luasLingkaran(double jarijari) { . Untuk membuat fungsi yang mengeluarkan suatu nilai kembali kepada pemanggilnya. yang apabila aturan-aturannya tidak dipenuhi secara disiplin mungkin akan menyebabkan bug atau kesalahan lain di luar kontrol kita. dan seri. komputer akan menghitung "ekspresi". yang disebut tipe keluaran. Fungsi biasanya dipanggil di tempat suatu nilai atau angka ditempatkan. misalnya ambilDouble("hallo"). userMenang. dengan bentuk return ekspresi. Misalnya. akan lebih masuk akal apabila subrutin bisa mengintip sedikit keluar dan saling menukar informasi jika cara ini jauh lebih mudah diimplementasikan dan dilihat dari dunia luar. Cara ini sebetulnya jalan belakang yang tidak terdokumentasi seperti pada definisi subrutin. dan ekspresi harus menghasilkan nilai yang memiliki tipe yang sama dengan tipe keluaran yang didefinisikan pada deklarasi subrutin tersebut. Dalam hal ini keluarannya akan diabaikan oleh komputer. Sebetulnya boleh-boleh saja memanggil suatu fungsi sendirian tanpa diletakkan di sebelah kanan tanda =. Pernyataan return ini hanya boleh ditulis di dalam sebuah subrutin (termasuk subrutin main()).oleh semua subrutin dalam kelas tersebut. yaitu apabila kelas secara keseluruhan dianggap sebagai kotak hitam. Suatu fungsi hanya dapat mengembalikan nilai dengan tipe tertentu.. Tipe Keluaran Suatu subrutin yang mengembalikan nilai disebut fungsi. Ketika komputer menjalankan pernyataan return. kita akan menghitung luas suatu lingkaran. kita harus memberikan pernyataan return. Fungsi dengan tipe keluaran boolean juga bisa ditempatkan sebagai kondisi pada pernyataan if atau while. dan kembali pada si pemanggil dengan membawa nilai hasil perhitungan "ekspresi". Kita buat fungsi luasLingkaran dengan parameter jarijari dan keluarannya bertipe double. Tidak ada yang salah dalam menggunakan variabel global. kadang-kadang program kita memang sengaja membuang nilai yang dikembalikan oleh fungsi karena satu dan lain hal. pada parameter sewaktu subrutin dipanggil. akan tetapi kita harus terus ingat bahwa variabel global itu harus sebagai bagian dari antar muka subrutin kita dengan keseluruhan dunia luar. menghentikan eksekusi subrutin tersebut saat itu juga. Paling tidak ada satu alasan untuk menggunakan variabel global. atau di tengah-tengah ekspresi yang panjang. Hal ini kita lihat pada contoh sebelumnya tentang subrutin dan variabel statik untuk menghitung statistik komputerMenang. Tergantung program yang akan kita buat. Perubahan yang terjadi di sini dapat mempengaruhi cara kerja subrutin lain yang menggunakan variabel tersebut. misalnya disebelah kanan tanda =.

Berikut ini adalah fungsi untuk menentukan nilai akhir (A. else return 'E'. if (nilaiUjian >= 90) . sehingga fungsi ini juga bisa diganti dengan "ruangkosong = 400 . else if (nilaiUjian >= 60) return 'D'.0.0. Ada juga beberapa programmer yang lebih suka dengan menggunakan variabel sementara kemudian perintah return diberi satu kali saja di akhir fungsi.314. akan tetapi pada fungsi perintah return wajib diberikan. D atau E) dari nilai ujian. tanpa ekspresi. perintah return diberikan.kita juga bisa menggunakan perintah return untuk langsung keluar dari subrutin tersebut.return 3.luasLingkaran(10). B. Ketika sampai pada bagian luasLingkaran. static char nilaiAlfa(double nilaiUjian) { if (nilaiUjian >= 90) return 'A'. } Anggap komputer sedang melakukan perintah "ruangkosong = 20*20 . static char nilaiAlfa(double nilaiUjian) { char keluaran.14 * jarijari * jarijari.".14 * 10. ia akan menghitung 3.luasLingkaran(10). Di dalam badan fungsi. C. } Perhatikan bahwa pada setiap cabang.0 * 10. else if (nilaiUjian >= 70) return 'C'. Di subrutin ini perintah return boleh diberikan jika diperlukan.yaitu subrutin yang tipe keluarannya void -. fungsi tersebut akan memasukkan 10 ke dalam parameter formal jarijari. else if (nilaiUjian >= 80) return 'B'."." Hasilnya yaitu 86 dimasukkan ke dalam variabel ruangkosong Dalam subrutin biasa -.0 yang hasilnya 314. Nilai ini akan dikembalikan kepada fungsi awalnya untuk menghitung "ruangkosong = 20*20 . seperti contoh berikut. yaitu dengan perintah return.

" maka ulang akan bernilai "AAAAAAAAAA" setelah fungsi ulangKarakter dijalankan. else if (nilaiUjian >= 70) keluaran = 'C'. akan semakin sulit dan kompleks tugas yang harus dilakukan oleh programmer. else keluaran = 'E'.keluaran = 'A'. int n) { String keluaran = "". Dan sebenarnya. seperti String pada contoh berikut. else if (nilaiUjian >= 80) keluaran = 'B'. else if (nilaiUjian >= 60) keluaran = 'D'. static String ulangKarakter(char c. Kita dengan mudah menulis program berbasis konsol . i <= n. return keluaran. 10). tipe keluaran bisa bertipe apa saja. Misalnya jika fungsi di atas kita panggil dengan "ulang = ulangKarakter('A'. } Fungsi di atas berfungsi untuk mengulang karakter c sebanyak n kali dan mengembalikan hasilnya. Toolbox. API. i++) keluaran = keluaran + c. // tambah karakter c ke dalam String keluaran sebanyak n kali for (int i = 1. } Contoh di atas memiliki tipe keluaran char. return keluaran. dan Paket Dengan semakin mudah digunakannya komputer. termasuk kelas.

kotak input teks. seperti jendela. bisa dijadikan kotak hitam yang sesungguhnya. Apple dan Linux memiliki toolbox sendiri yang berbeda dengan yang disediakan oleh Windows. . tipe data String. Windows API adalah spesifikasi semua subrutin yang tersedia dalam toolbox Apple. Perusahaan yang membuat hardware. Contoh API yang pernah kita lihat misalnya Math. misalnya untuk membuka dan menutup jendela. Bagian yang inovatif adalah bagaimana merangkai alat tadi menjadi sesuatu yang berguna untuk suatu proyek atau suatu masalah yang ingin dipecahkan (pengolah kata. Bahasa pemrograman Java juga didukung oleh API yang cukup besar dan standar. yaitu koleksi dari ribuan subrutin. yang paling dasar adalah apa yang diberikan oleh bahasa pemrograman itu sendiri. Ini disebut pemrograman aplikasi. menambah tombol dan menerima respon dari user. misalnya sound card atau blue tooth mungkin juga akan membuat API untuk perangkat tersebut yang berisi subrutin yang diperlukan programmer untuk bisa menggunakan perangkat itu. jika didesain dengan sangat baik. programmer bisa menambahkan toolbox yang berisi subrutin yang sudah ditulis untuk melakukan tugas tertentu. dan lain-lain. Mungkin lebih mudah jika API ini dianggap sebagai bagian dari bahasa Java. dll). untuk komunikasi network. Intinya di dalam toolbox terdapat segala sesuatu yang menurut kita standar. Setiap proyek pembuatan program akan terdiri dari inovasi (sesuatu yang sangat baru) dan menggunakan kembali sesuatu yang sudah pernah dibuat sebelumnya. Di atasnya. perulangan. dan lain-lain. browser. game. Java API standar terdiri dari subrutin untuk membuat dan mengendalikan GUI. Toolbox suatu software adalah juga kotak hitam. Alat ini. Informasi ini disebut API (Applications Programming Interface = Antarmuka Pemrograman untuk Aplikasi). Peneliti yang membuat program untuk menyelesaikan suatu perhitungan matematis kompleks -. Seseorang yang ingin membuat program untuk Windows misalnya. Selain GUI ada juga subrutin yang berurusan dengan membuka. Antar muka ini berisi spesifikasi tentang rutin-rutin apa saja yang ada di sana. dan subrutin yang terkait. membaca.dengan menggunakan beberapa subrutin untuk menampilkan pesan dan mengambil input dari user. dan lebih banyak subrutin yang harus dibuat untuk bisa mengontrol setiap komponen GUI.juga akan membuat API sehingga orang lain bisa menggunakan subrutinnya tanpa harus mengerti dengan detail bagaimana perhitungan itu dilakukan. dan tugas apa yang mereka lakukan. Seorang programmer diberi peralatan untuk berhasil dalam proyeknya tersebut. tombol. dan menulis file.misalnya persamaan diferensial -. untuk menggambar dan menulis teks. akan tetapi sebetulnya API terdiri dari subrutin yang bisa digunakan dalam program Java. dan lain-lain mungkin lebih menarik bagi user. scroll bar. menu. yaitu kotak hitam yang kita betul-betul tidak perlu tahu bagaimana dia bekerja. berkomunikasi dengan network. harus menggunakan Toolbox Windows. Akan tetapi programmer harus berhadapan dengan kemungkinan yang sangat amat banyak. misalnya variabel.random(). apa parameter yang dibutuhkan. baca tulis file. Ia memiliki antar muka dengan programmernya. GUI (graphical user interface = antarmuka pengguna berbasis grafik). dan lain-lain.

seperti kelas Button yang melambangkan tombol. Paket java sendiri terdiri dari beberapa sub paket lain. Suatu paket dapat terdiri dari kelas ataupun pake lain. Untuk membuat organisasi lebih baik. Paket java dan javax juga memiliki beberapa sub paket. Di dalam paket ini terdapat kelas-kelas fundamental misalnya String dan Math. Seperti subrutin pada Java. Karena awt berada di dalam paket java. sub paket. atau Graphics yang merupakan kumpulan rutin untuk menggambar di monitor. Sistem Java pada suatu komputer terdiri dari implementasi pada komputer tersebut.awt.applet mengimplementasikan fungsi dasar untuk applet.swing.awt. java. seperti java.Button dan java. Salah satu sub paket java.io yang sudah kita pakai dalam bab-bab sebelumnya.awt.lang.Graphics.swing. Java API yang sama harus bisa bekerja dengan semua sistem. misalnya disebut awt.Java merupakan bahasa yang tidak tergantung pada mesin atau sistem operasi di mana ia dijalankan. dan subrutin di dalam kelas. maka nama lengkapnya adalah java. kelas di dalam sub paket. yang berisi paket-paket non-GUI dan juga GUI berbasis AWT. Karena kelas ini tergabung dalam paket java. yaitu "javax".JApplet. dan java. subrutin pada API standar dikelompokkan ke dalam kelas.2.JButton dan javax. Kita juga bisa membuat hirarki paket yang lebih tinggi. nama lengkapnya adalah java.swing. Salah satu paketnya bernama "java". . Mungkin akan lebih jelas jika kita lihat ilustrasi berikut tentang tingkatan paket java. berguna untuk memberikan fasilitas input/output.awt. Kenyataannya seluruh API standar Java diimplementasikan dalam beberapa paket. Implementasinya bisa sangat berbeda antara satu sistem operasi dengan lainnya. berisi kelas yang digunakan untuk GUI Swing. kelas Java dapat digabungkan menjadi paket. Program Java yang kita buat memanggil subrutin pada komputer tersebut. yang ditambahkan pada versi 1. yang terdiri dari kelas yang bernama javax.net untuk mengendalikan komunikasi jaringan. Ketika komputer menjalankan program dan sampai pada perintah untuk memanggil subrutin pada API. komputer akan menjalankan implementasi subrutin yang sesuai dengan sistem komputer di mana program tersebut dijalankan. Artinya. kita hanya perlu belajar satu API saja untuk melakukan pemrograman pada berbagai macam komputer dan sistem operasi. Paket lain. Paket inilah yang sebenarnya memiliki kelas-kelas GUI AWT. Demikian juga dengan javax yang memiliki sub paket yang bernama javax. karena paket juga bisa berisi paket lain. Paket yang terdapat di dalam paket lain disebut "sub paket". Akan tetapi ingat bahwa yang sama adalah antar mukanya. Paket yang paling dasar disebut java.

Ingat pada kode kita sebelumnya yang berbentuk seperti ini? import java.awt. sehingga menjadi Color warnaKotak.awt. di awal program. Seandainya perintah import tidak kita berikan. misalnya java.io. Tentu saja akan terlalu cape jika kita harus menulis nama kelas dengan lengkap setiap kali akan digunakan.*.) Ada lagi jalan pendek untuk mengimport seluruh kelas pada suatu paket. (Satu-satunya keuntungan yang diberikan perintah import adalah untuk menyingkat penulisan nama kelas. bukan untuk mengimport keseluruhan kelas ke dalam program kita.Color.awt. kita bisa menyingkat java.Color hanya dengan nama kelasnya saja.awt dengan import java. Java mengijinkan kita untuk menggunakan langsung nama kelasnya jika kita berikan perintah import. dan kita panggil dengan nama lengkapnya.Color warnaKotak.Misalkan kita akan menggunakan kelas java. dan kemudian di bagian lain.awt. untuk mendekalarasi variabel bernama warnaKotak yang tipenya adalah java.awt. seperti import java. Salah satu caranya adalah dengan menggunakan nama lengkap dari kelas tersebut.*. Kita bisa import seluruh kelas di dalam paket java. Java akan tetap bisa mengakses kelas tersebut.awt.Color dalam program. .Color.

dan direktori tersebut harus diletakkan pada direktori yang sama dengan program yang akan menggunakan kelas itu.awt.Ketika program yang akan kita buat semakin besar.util memiliki kelas yang bernama List.*.List atau java. Tentunya lebih pas tergantung dari lingkungan Java yang kita lakukan. java akan menampilkan pesan kesalahan tentang adanya nama kelas yang membingungkan. Satu hal penting yang perlu diingat adalah ada kemungkinan beberapa paket memiliki nama kelas yang sama. Ingat bahwa ketika suatu program menggunakan kelas. maka sangat masuk akal apabila kita membagi dan mengorganisir kelas tersebut dalam satu atau beberapa paket.lang.lang. Banyak sekali tetek bengek detail di dalam deklarasi dan menggunakan nama. Misalnya java.util.lang.sqrt(). Misalnya kita akan membuat kelas yang akan diletakkan di paket yang bernama alatbantu. Dan juga masuk akal untuk membuat paket baru sebagai toolbox atau dengan kata lain membuat API baru yang belum dikover oleh API Java. setiap kelas dalam java. Pada saat program kita besar. maka perubahan yang diperlukan untuk mengorganisir akan lebih signifikan. biasanya paket yang bernama alatbantu harus berada di dalam direktori alatbantu. Menggabungkan Inisialisasi dan Deklarasi .List. Karena paket java. Masalahnya hal ini agak sedikit lebih rumit." Program lain yang menggunakan paket ini bisa menambah "import alatbantu. bukan java.*. Artinya.". kita bisa memanggil kelas seperti String saja. Bab ini menjelaskan lebih detail tentang paket. Seakan-akan semua program dimulai dengan perintah "import java. atau Math. (Seringkali orang yang membuat API lebih disanjung akan kehebatannya dibandingkan dengan orang yang hanya menggunakan API).* dan java. maka kelas tersebut harus "tersedia" ketika program tersebut dikompilasi dan ketika program terus dieksekusi. Solusinya? Gunakan nama lengkap kelasnya.awt.Math.* adalah paket yang sangat penting. maka nama List menjadi rancu.awt dan java. maka ada kemungkinan kita harus mengimport banyak paket.util. Jika kita mencoba membuat variabel dengan tipe data List. yaitu java.lang akan diimport otomatis ke dalam semua program. Sebetulnya tidak ada salahnya kita mengorganisir setiap program yang kita buat sejak awal. Dalam bagian ini akan kita singgung beberapa hal penting tentang deklarasi dan penggunaan variabel pada Java. Pada program yang menggunakan banyak kelas. Programmer juga bisa membuat paket baru. Maka pada awal program kita harus didefinisikan dengan perintah "package alatbantu. Tentang Deklarasi Nama adalah hal yang paling dasar dalam pemrograman.lang.String. kita sudah menggunakan paket dari awal.sqrt() bukan java." untuk mengabmbil semua kelas dalam paket alatbantu. Jika kita import kedua kelas dengan perintah java.*. Dalam program Eclipse kita.

Misalnya.out. karena N sudah diberi nilai awal sebelum digunakan oleh M Fitur ini biasa ditemui pada perulangan for. Pada variabel lokal. for ( i = 0. i++ ) { System. Misalnya for ( int i = 0. Saya sengaja tambahkan { dan } di awal dan akhir untuk mempertegas bahwa i hanya bersifat lokal di dalam perulangan yang tidak bisa diakses lagi setelah perulangan selesai. komputer akan menyiapkan memori untuk digunakan oleh variabel ini. // Ok. Karena variabel kontrol biasanya tidak berhubungan dengan bagian program di luar perulangan.println(i). maka akan lebih praktis jika deklarasi variabel kontrol itu dilakukan di awal perulangan. tapi hanya akhir yang akan diinisialisasi // Ok. i < 10. int awal. } . y = 1. int N = 3. int i. Nilai awal tidak harus berupa suatu bilangan. { int i. karena pernyataan 1 baris ini bisa dimasukkan sebagai variabel kontrol di awal pernyataan for. Kedua pernyataan di atas bisa kita gabung menjadi int i = 0.println(i).out.Ketika perintah deklarasi variabel dilaksanakan. i++ ) { System. // Deklarasi variabel yang bernama i // Beri nilai awal Kita bisa juga melakukan deklarasi sekaligus inisialisasi variabel tersebut. Misalnya. } Perlu diingat bahwa ekspresi di atas merupakan singkatan dari blok berikut. akhir = 'A'. Dan juga kita boleh melakukan inisialisasi beberapa variabel sekaligus dalam 1 baris. tetapi bisa juga berupa ekspresi yang menghasilkan suatu nilai. // Deklarasi variabel i sekaligus memberi nilai awal 0 Komputer akan tetap melakukan perintah di atas dalam dua langkah: deklarasi variabel. kemudian mengisi nilai awal 0. yaitu diberi suatu nilai awal sebelum bisa digunakan dalam perintah berikutnya. i = 0. pernyataan deklarasi sering diikuti oleh perintah pemberi nilai awal. M = N+2. Memori ini harus diinisialisasi. i < 10. int x = 0.

perintah ini harus ada di dalam subrutin . } Karenanya. sifat "final" bisa digunakan pada deklarasi variabel untuk membuat nilai suatu variabel tidak bisa diubah setelah diinisialisasi. // sama dengan 10% static long maxPenarikan = 2000000. .1. Jika tidak ada nilai awal yang diberikan. kita ingin nilai suatu variabel tidak boleh berubah setelah diberi nilai awal. sedangkan inisialisasi tidak bisa dilakukan di luar subrutin. Pernyataan deklarasi adalah pernyataan yang bisa dibuat di luar subrutin. inisialisinya pun dilaksanakan pada saat itu.". public class Bank { static double sukuBunga. public class Bank { static double sukuBunga = 0. . Misalnya // ILEGAL. deklarasi variabel anggota biasanya juga dirangkai dengan inisialisasi nilai awalnya.14159.14159*diameter. Konstanta dan Sifat "final" Kadang-kadang dalam kondisi tertentu.14159.1." daripada "pokok = 3. // Perintah dan variabel lain . deklarasi dan inisialisasi ini bukan hanya sekedar singkatan dari 2 perintah seperti pada variabel lokal. Misalnya "static int i. pi diinisialisasi dengan nilai 3.} Variabel anggota juga bisa diinisialisasi di mana dia dideklarasikan. Pada variabel anggota. Dengan cara ini. maka nilai awal bawaan akan digunakan. Dalam java. maka nilai ini akan bisa diubah oleh bagian lain dalam program.". Misalnya. Di sini mungkin sang programmer ingin mendefinisikan suatu konstanta yang diberi nama "pi" sebagai pengganti dari bilangan 3." setara dengan "static int i = 0. sukuBunga = 0. program akan lebih mudah dimengerti apabila program tersebut ditulis dalam "keliling = pi*diamater. } Variabel anggota statik akan dibuat pada saat kelas mulai dimasukkan memori oleh interpreter Java. Contoh di bawah tidak diperbolehkan dalam Java. Misalnya.

PLAIN. Misalnya. Bagian di dalam kode sumber (yaitu program Java yang kita tulis.final static double pi = 3. seperti Font. Font.1 di dalam program untuk menggantinya satu per satu. bank tersebut ingin mengubah suku bunganya menjadi 5% atau 0. komputer akan menyediakan tempat di memori untuk variabel tersebut. Kita tidak perlu mencari semua nilai 0. . Misalnya kita definisikan sukuBunga pada contoh di atas sebagai konstanta bernama.1 bisa digunakan untuk nilai lainnya. maka kita harus mengkompilasi ulang program kita. sehingga kita tidak perlu mendefinisikannya sendiri. tetapi juga nama subrutin dan nama parameter formal. Apabila kita mencoba mengganti isi variabel tersebut. Selain repot. Bukan hanya variabel yang memiliki jangkauan. Kita bisa mengubah nilainya hanya di satu tempat yaitu di mana deklarasi SUKU_BUNGA berada. misalnya di tengah program dengan perintah "pi = 20. Gaya penulisan seperti ini juga digunakan oleh kelas standar Java. Contoh lain adalah memberikan nama untuk gaya huruf. Gaya penulisan yang dianjurkan untuk konstanta bernama ini adalah dengan menggunakan huruf besar dengan baris bawah (jika diperlukan). Variabel anggota statik yang dideklarasikan dengan sifat "final" juga disebut sebagai konstanta yang diberi nama. akan tetapi paling berguna apabila diberikan pada variabel anggota. karena nilai ini tidak bisa diubah ketika program dieksekusi. yaitu static final double SUKU_BUNGA = 0. konstanta PI sudah didefinisikan Java dalam kelas Math.14159. Apabila nilai ini diubah.PI. masih dalam bentuk yang dimengerti manusia sebelum dikompilasi menjadi bahasa mesin) di mana variabel tersebut valid dan bisa digunakan disebut jangkauan variabel. Nama variabel dapat digunakan oleh kode program untuk mengacu pada alamat di mana data tersebut disimpan di dalam memori. Salah satu alasan utama untuk menggunakan konstanta bernama adalah supaya kita bisa mengubah isinya dengan cepat apabila di kemudian hari kita ingin memiliki nilai konstanta yang berbeda. bukan hanya nilai suku bunga. Program akan jauh lebih mudah dibaca dengan menggunakan konstanta bernama ini jika diberikan pada sesuatu angka penting yang digunakan dalam program. Konstanta ini digunakan untuk menandai gaya huruf untuk digunakan oleh subrutin lain dalam kelas Font. Sifat "final" boleh diberikan pada variabel lokal dan bahkan pada parameter formal. yaitu Math.05.BOLD dan Font." komputer akan menampilkan pesan kesalahan sintaks pada saat kompilasi.1. yang di dalamnya terdapat banyak sekali konstanta bernama.ITALIC. Misalnya final static double PI = 3. Suatu saat misalnya 2 tahun kemudian. mungkin membingungkan karena 0. Aturan Penamaan dan Jangkauan (scope) Ketika deklarasi variabel dieksekusi.14159.

. jangkauannya lebih mudah dipahami. Di luar kelas Game. } // akhir kelas Game Kita lihat bahwa dalam subrutin mainGame(). Misalnya. tetapi dengan sedikit pengecualian. tetapi tidak valid di luar perulangan ini meskipun pada subrutin yang sama. Dalam situasi seperti ini. yaitu subrutin yang memanggil dirinya sendiri. Untuk variabel anggota suatu kelas.hitung. di dalam subrutin mainGame() maka "hitung" sebagai variabel anggota akan disembunyikan oleh Java. teknik ini disebut rekursi (recursion). Akan tetapi kita tidak boleh mendeklarasikan parameter formal dengan nama yang sama dengan variabel lokal yang berlaku di sana. Dalam pemrograman tingkat lanjut. Teknik ini digunakan dalam bab yang akan datang yang berbicara detail tentang struktur data dan algoritma. // Variabel dan subrutin lain . maka variabel anggota akan disembunyikan oleh Java. Sehingga pada "for (int i=0. Kita boleh memiliki variabel lokal atau parameter formal yang namanya sama dengan variabel anggota static. i++)" variabel i hanya bisa di lihat di dalam blok perulangan for. Dalam contoh berikut : public class Game { static int hitung. Untuk menggunakan variabel anggota ini. aturannya sama. . } . // variabel anggota static void mainGame() { int hitung. kita bisa menggunakan nama lengkapnya yaitu Game. "hitung" mengacu pada dua hal yaitu variabel lokal dan variabel anggota statik. Akan tetapi trik ini tidak bisa digunakan untuk variabel anggota yang tidak statik. i<10. // Perintah untuk main game . "hitung" hanya mengacu pada variabel anggota statik.Untuk subrutin statik. . Jangkauan parameter formal di dalam suatu subrutin berada di dalam blok di mana ia dideklarasikan. Kita bisa juga memanggil subrutin itu dari dalam kelas dirinya sendiri. Jika ini terjadi. Jangkauan subrutin statik adalah kelas di mana ia didefinisikan. // variabel lokal .

. Misalnya. Akan tetapi pada Java. pernyataan di atas masih dibolehkan. . segera setelah blok yang memuat suatu variabel selesai. . . void subrutinBagus(int y) { while (y > 10) { int x. .void subrutinJelek(int y) { int x. // Jangkauan x berakhir di sini } while (y > 0) { int x. . // ERROR: x sudah didefinisikan sebelumnya . . yaitu dengan menyembunyikan x pada deklarasi sebelumnya. } } Dalam bahasa pemrograman lain. } } . // OK: Deklarasi x sebelumnya sudah kadaluarsa . namanya bisa dipergunakan kembali. while (y > 0) { int x.

Ada beberapa hal lain yang menarik di Java. Nama subrutin dan variabel boleh sama, karena komputer akan selalu dapat membedakan mana subrutin atau variabel dengan melihat tanda buka kurung '(' setelah namanya. Variabel tidak pernah menggunakan tanda kurung setelah namanya. Sehingga suatu kelas boleh memiliki variabel anggota yang bernama "hitung" dan subrutin yang bernama "hitung()". Lebih jauh lagi, nama suatu kelas boleh menggunakan nama subrutin atau variabel yang sudah ada. Komputer bisa melihat apakah suatu nama berupa kelas, variabel atau subrutin. Kelas adalah juga tipe data, sehingga suatu kelas bisa digunakan untuk mendeklarasikan variabel dengan tipe kelas tersebut, atau membuat subrutin yang keluarannya bertipe kelas tersebut. Atau sebagai contoh, perintah berikut bisa diterima oleh program Java : static Gila Gila(Gila Gila) { . . . } Gila pertama adalah tipe keluaran suatu fungsi. Gila kedua adalah nama subrutin. Yang ketiga adalah tipe data parameter, dan keempat adalah nama parameter formal. Tetapi, ingat tidak semua yang mungkin dan boleh dilakukan berarti harus dilakukan.

Bab VI - Pemrograman Berorientasi Objek
Jika subrutin hanya melambangkan suatu tugas, objek merupakan gabungan data (dalam bentuk variabel instansi - atau "instance variable") dan beberapa tugas atau disebut "perilaku" terhadap kumpulan data tersebut (dalam bentuk metode instansi - atau "instance method"). Oleh karena itu objek merupakan stuktur baru yang dapat menangani semakin rumitnya kompleksitas suatu program Bagian ini meliputi pembuatan dan penggunaan objek dalam bahasa Java. Juga akan dibahas inti tentang pemrograman berorientasi objek, yaitu : pewarisan dan poli morfisme (perubahan wujud).
• • • • •

Objek, Metode Instansi dan Variable Instansi Konstruktor dan Inisialisasi Objek Pemulung Memori (Garbage Collector) Pewarisan, Polimorfisme, dan Kelas Abstrak this dan super

Antar Muka (interface), Kelas Bertingkat, dan Detail Lain

Objek, Metode Instansi dan Variable Instansi
Pemrograman berorientasi objek bermaksud untuk memecahkan masalah programming mirip dengan cara berfikir manusia dan bagaimana manusia berinteraksi dengan dunia. Kita telah melihat bagaimana masalah programming dipecahkan dengan membaginya menjadi instruksiinstruksi kecil yang dirangkai menjadi suatu kesatuan tugas. Cara ini disebut juga dengan pemrograman berdasarkan prosedur. Pada pemrograman berorientasi objek, kita membagi masalah pemrograman berdasarkan objek atau "sesuatu" benda. Objek ini diibaratkan seperti makhluk hidup, yaitu memiliki ciri-ciri fisik dan juga perilaku. Dalam pemrograman berorientasi objek, ciri-ciri fisik ini disebut juga sebagai atribut, pada dasarnya berisi informasi tentang objek tersebut. Sedangkan perilaku disebut sebagai metode, yaitu bagaimana suatu objek bertindak atau melakukan sesuatu. Dengan cara ini diharapkan pemrograman berorientasi objek merupakan pemrograman yang lebih alami dibandingkan dengan pemrograman berorientasi prosedur, karena cara fikir kita sudah terbiasa dengan bagaimana kita berinteraksi dengan dunia. Sampai tingkat tertentu, PBO hanya merubah cara pandang programmer. Objek dalam kaitannya dengan dasar pemrograman adalah gabungan dari variabel (dalam hal ini atribut) dan subrutin (yaitu metode) yang berinteraksi dengan variabel pada objek. Banyak bahasa pemrograman lain yang juga mendukung konsep PBO, akan tetapi Java merupakan bahasa yang mendukung penuh PBO, di antaranya karena Java memiliki beberapa fitur penting yang berbeda dari bahasa standar. Untuk menggunakan fitur ini, kita harus mengubah cara pandang kita terlebih dahulu. Objek terkait erat dengan kelas. Kita telah bahas dan mencoba beberapa contoh kelas pada bab-bab sebelumnya. Seperti kita lihat pula bahwa kelas memiliki variabel dan subrutin. Jika objek juga memiliki variabel dan subrutin, lalu apa bedanya dengan kelas? Lalu mengapa kita harus memiliki cara pandang berbeda dengan cara kita melihat kelas? Sepertinya apabila kita lihat contoh-contohnya sebelumnya, perbedaannya hanya menghilangkan kata "static" dari deklarasi variabel dan subrutinnya, khan? Seperti disebutkan sebelumnya bahwa kelas mendeskripsikan suatu objek, atau lebih tepatnya, bagian non "static" mendeskripsikan suatu objek. Mungkin bahasa biologi, kelas adalah species, sedangkan objek merupakan individu. Human sapiens (nama biologi manusia) adalah kelas, sedangkan Anda, saya, ibu, bapak, pak hansip adalah objek. Masing-masing dari kita memiliki "blueprint" atau cetak biru yang sama, tetapi kita memiliki ciri-ciri yang berbeda, rambut, mata, telinga, tinggi badan, berat badan, dan juga perilaku kita saat makan, minum, belajar, dan lain-lain. Dalam sudut pandang pemrograman, kelas digunakan untuk menciptakan suatu objek. Atau dengan kata lain, kelas adalah pabrik pembuat objek. Bagian non-statik dari suatu kelas adalah bagian yang memuat detail suatu objek, yaitu apa isi variabel dan metodenya. Perbedaan kelas

dan objek adalah : Objek diciptakan dan dihancurkan ketika program berjalan, sehingga kita bisa memiliki beberapa objek sekaligus. Kita lihat contoh sederhana, dimana kelas sederhana digunakan untuk menggabungkan beberapa variabel statik. Misalnya class DataPenduduk { static String nama; static int umur; } Pada program yang menggunakan kelas ini, hanya ada satu kopi dari setiap variabel DataPenduduk.nama dan DataPenduduk.umur. Hanya akan ada satu penduduk, karena kita menyimpan data tersebut sebagai data statik, yang artinya hanya satu tempat di memori di mana data tersebut disimpan. Kelas DataPenduduk dan variabel isinya akan ada selama program tersebut berjalan. Sekarang kita lihat kode berikut yang memiliki variabel non-statik: class DataPenduduk { String nama; int umur; } Dalam hal ini tidak ada lagi yang variabel DataPenduduk.nama dan DataPenduduk.umur, karena nama dan umur bukan anggota statik kelas DataPenduduk. Jadi, tidak ada yang bisa kita lakukan dengan kelas ini sama sekali, kecuali membuat objek dari kelas ini. Setiap objek akan memiliki variable sendiri yang dinamakan "nama" dan "umur". Kita bisa membuat banyak "penduduk" karena kita bisa membuat objek untuk setiap penduduk. Misalnya setiap kali seseorang dilahirkan, kita bisa membuat objek penduduk baru. Atau jika seseorang meninggal dunia, kita bisa hapus objek tersebut. Suatu sistem yang terdiri dari kumpulan objek digunakan untuk memodelkan apa yang terjadi di alam nyata. Kita tidak bisa membuat beberapa objek dengan menggunakan variabel statik. Contoh lainnya adalah pada GUI. Bayangkan kita memiliki beberapa tombol, misalnya tombol OK, Cancel dan Apply. Masing-masing tombol ini memiliki kelas yang sama akan tetapi apa yang dilakukan tombol ini berbeda-beda. Teks yang ditampilkan (OK, Cancel atau Apply) merupakan variabel masing-masing objek.

Suatu objek yang diciptakan dari suatu kelas disebut instansi dari kelas tersebut. Variabel yang dimiliki oleh objek disebut variabel instansi. Sedangkan subrutinnya disebut . (Dalam PBO subrutin disebut metode) Misalnya dalam kelas DataPenduduk di atas, kemudian kita buat suatu objek dari kelas ini, maka objek yang diciptakan disebut instansi dari kelas DataPenduduk, "nama" dan "umur" adalah variabel instansi di dalam objek tersebut. Penting untuk diingat bahwa kelas suatu objek menentukan tipe data dari variabel instansi, akan tetapi isi datanya sendiri tidak disimpan di dalam kelas, akan tetapi di dalam objek yang diciptakan, sehingga setiap objek akan memiliki data masing-masing. Begitu juga dengan metode instansi, misalnya pada kelas tombol, kita memiliki metode yang dinamakan klik(). Masing-masing tombol akan melakukan tugas berbeda-beda tergantung dari objeknya. Seperti kita lihat di sini bahwa bagian statik dan non-statik dari suatu kelas merupakan hal yang sama sekali berbeda. Banyak kelas yang hanya memiliki anggota statik, atau hanya memiliki anggota non-statik. Akan tetapi kita juga bisa mencampur keduanya dalam suatu kelas. Variabel anggota statik suatu kelas juga bisa disebut variabel kelas dan metode anggota statik suatu kelas juga bisa disebut metode kelas, karena mereka adalah milik kelas dan bukan milik objek yang diciptakan dari suatu kelas. Sekarang kita gunakan contoh yang lebih real. Kita akan buat versi sederhana dari kelas Murid, dimana kita akan menyimpan informasi tentang murid yang terdaftar pada suatu sekolah. class Murid { String nama ; // nama murid // nilai ulangan murid tersebut // hitung rata-rata nilai ulangan

double nilai1, nilai2, nilai3; double hitungRataRata() {

return (nilai1 + nilai2 + nilai3) / 3; } } Kita lihat bahwa semua anggota kelas tersebut bukan anggota statik, artinya kelas ini hanya bisa digunakan untuk membuat objek. Definisi kelas ini artinya bahwa di dalam objek yang akan diciptakan, akan ada variabel instansi yang bernama nama, nilai1, nilai2, dan nilai3, dan juga metode instansi yang bernama hitungRataRata(). Setiap murid memiliki nilai rata-rata yang berbeda-beda. (Makanya ini disebut perilaku suatu objek berbeda-beda). Dalam Java, kelas merupakan tipe data, yaitu mirip dengan tipe data bawaan seperti int atau boolean. Jadi nama kelas bisa digunakan untuk menentukan tipe suatu variabel dalam deklarasi

pernyataan, dalam parameter formal dan juga dalam tipe keluaran suatu fungsi. Misalnya, program mendefinisikan seorang murid dengan pernyataan seperti : Murid amir; Akan tetapi membuat variabel seperti di atas TIDAK menciptakan objek. Initinya, ini adalah hal Yang Sangat Amat Penting : Dalam Java, tidak ada variabel yang bisa menyimpan objek. Variabel hanya bisa menyimpan referensi (alamat di memori) suatu objek. Komputer akan menggunakan referensi ini untuk mencari objek di dalam memori. Objek diciptakan dengan pernyataan new, yang bertugas menciptakan objek kemudian mengembalikan referensi ke objek yang sudah diciptakan. Misalnya amir adalah variabel dengan tipe Murid seperti dideklarasikan di atas, maka pernyataan berikut : amir = new Murid(); akan membuat objek yang merupakan instansi dari kelas Murid. Variabel amir akan menyimpan referensi ke objek yang baru saja diciptakan. Sekarang anggap variabel amir merujuk pada objek yang diciptakan dari kelas Murid. Dalam objek tersebut terdapat variabel nama, nilai1, nilai2, dan nilai3. Variabel instansi ini bisa dipanggil dengan amir.nama, amir.nilai1, amir.nilai2, dan amir.nilai3. (Ingat aturan penulisan nama lengkap, akan tetapi karena kelas ini tidak memiliki anggota statik, dan hanya objek yang diciptakan dari kelas ini memiliki variabel atau metode ini, maka nama lengkapnya diturunkan dari nama objek yang memilikinya). Misalnya, program berikut : System.out.println("Hai, " + amir.nama + " . Nilai Anda adalah : "); System.out.println(amir.nilai1); System.out.println(amir.nilai2); System.out.println(amir.nilai3); Program di atas akan mencetak nama dan nilai-nilai yang disimpan oleh objek amir. Begitu juga kita bisa menghitung rata-rata pada suatu objek dengan menggunakan amir.hitungRataRata(). Sehingga untuk menghitung rata-rata murid tersebut, bisa kita perintahkan dengan: System.out.println("Nilai rata-rata Anda adalah : " + amir.hitungRataRata()); Lebih umum lagi, kita bisa menggunakan amir.nama seperti layaknya variabel bertipe String, artinya kita bisa menghitung jumlah karakter dengan menggunakan amir.nama.length(). Kita juga bisa membuat variabel seperti amir untuk tidak menunjuk atau memiliki referensi ke obek mana pun. Dalam hal ini kita sebut bahwa objek amir berisi referensi kosong (null

reference). Referensi kosong ini ditulis dalam Java dengan ekspresi "null". Dan kita bisa menyimpan nilai "null" pada variabel amir dengan perintah : amir = null; Dan kita juga bisa uji apakah amir berisi referensi kosong dengan perintah if (amir == null) . . . Jika suatu variabel berisi referensi kosong, maka tentu saja, kita tidak bisa mengambil variabel instansi dan menjalankan metode instansi, karena tidak ada objek yang dirujuk pada variabel tersebut. Misalnya jika variabel amir berisi null, maka kita tidak bisa mengambil variabel amir.nilai1. Jika program kita mencoba mengakses referensi kosong secara ilegal, maka di tengah-tengah jalannya program, program akan menampilkan pesan kesalahan "null pointer exception". Mari kita lihat beberapa pernyataan yang bisa digunakan dengan objek : Murid mrd1, mrd2, mrd3, mrd4; // mendeklarasikan 4 variabel yang bertipe Murid

mrd1 = new Murid(); // membuat objek baru dari kelas Murid, kemudian menyimpan referensinya pada variabel mrd1 mrd2 = new Murid(); // membuat objek baru dari kelas Murid, kemudian menyimpan referensinya pada variabel mrd2 mrd3 = mrd1; mrd4 = null; // menkopi „referensi" yang disimpan pada mrd1 ke mrd3 // menyimpan referensi kosong ke mrd4

mrd1.nama = "Ahmad Surahmat"; mrd2.nama = "Hamid Samsudin";

// mengisi nilai variabel instansi

Setelah komputer menjalankan program tersebut, maka kira-kira memori komputer akan tampak seperti gambar berikut :

Gambar tersebut menunjukkan variabel dalam kotak-kotak kecil dengan nama variabelnya. Objek ditunjukkan dalam kotak dengan pojok bulat. Ketika suatu variabel berisi referensi ke suatu objek, maka nilainya adalah seperti panah yang menunjuk pada objek tersebut. Variabel mrd4 bernilai null, sehingga tidak menunjuk ke mana-mana. Panah dari mrd1 dan mrd3 menjunjuk pada objek ang sama. Ini merupakan Hal Yang Sangat Penting : Jika isi variabel suatu objek diberikan kepada variabel yang lain, maka yang dikopi hanya referensinya saja. Isi objek tidak pernah dikopi. Ketika pernyataan "mrd3 = mrd1;" dieksekusi, tidak ada objek baru yang dibuat. Akan tetapi mrd3 akan merujuk pada alamat yang sama seperti mrd1. Konsekuensinya mungkin sedikit mengejutkan. Misalnya variabel mrd1.nama dan mrd3.nama menunjuk pada variabel yang persis sama, maka apabila mrd1.nama disi dengan "Juju Juminten", maka mrd3.nama juga berisi "Juju Juminten". Sekali lagi, variabel tidak berisi objek, akan tetapi berisi referensi ke suatu objek. Kita bisa menguji beberapa objek dengan operator == dan != untuk menguji kesamaan dan ketidaksamaan. Akan tetapi yang dicek lagi-lagi bukan isi objek, melainkan alamat memori dimana objek tersebut dijadikan referensi. Jika alamat referensi di memori sama, artinya kedua

Seperti disebutkan pada bagian sebelumnya. Pada saat objek dibuat. Apabila ada variabel lain yang tidak "final" tetapi menunjuk pada alamat memori yang sama. sedangkan isi variabel itu adalah rujukan ke alamat memori tempat objek berada.objek tersebut merujuk pada alamat memori yang sama. Kita boleh saja untuk menulis perintah sebagai berikut. murid.equals(mrd1. komputer akan mencari tempat yang tidak . Ingat == pada objek bukan membandingkan isi objek.nilai2 && mrd3. Perhatikan pada kode di atas bahwa isi objek bisa diubah. Akan tetapi hal ini tidak berlaku untuk objek itu sendiri.nilai3 == mrd1. Dengan demikian variabel tersebut akan selalu menunjuk pada alamat memori yang sama.nilai1 && mrd3. final Murid mrd = new Murid().nilai3 && mrd3. yaitu misalnya dengan "mrd3. kemudian variabel ini mengubah isi objek tersebut. Sehingga membandingkan String yang satu dengan String yang lain dengan menggunakan tanda == adalah membandingkan apakah alamat memori yang ditunjuk oleh String yang satu sama dengan alamat memori yang ditunjuk oleh String yang lain. Untuk membandingkan isi String. mendeklarasikan suatu variabel dengan tipe suatu kelas tidak berarti membuat objek dari kelas tersebut. Untuk menguji isinya.nilai1 == mrd1. maka isi objek tersebut bisa berubah.nama)" Seperti telah disebutkan sebelumnya bahwa String juga merupakan objek. Misalnya. Metode ini akan membandingkan karakter per karakter dari kedua String. maka isinya harus dibandingkan satu per satu.equals("Selamat") Konsekuensi lainnya adalah apabila suatu variabel merujuk pada objek yang dideklarasikan sebagai final.nilai2 == mrd1. Objek tersebut harus dibuat (constructed). tetapi membandingkan alamat memori yang ditunjuk oleh variabel tersebut. seperti int atau boolean. kita dapat menggunakan String. Ini berarti nilai variabel itu tidak bisa berubah setelah diinisialisasi. Ini berarti perubahan yang dilakukan pada variabel yang satu akan ikut mempengaruhi variabel yang lain.nama. Untuk menguji apakah variabel salam berisi "Selamat". // ILEGAL.nama = "Ahmad Basir". bisa kita gunakan perintah salam. mrd = mrd99.equals() di mana parameternya adalah objek String yang akan dibandingkan. karena mrd adalah variabel final Konstruktor dan Inisialisasi Objek Kelas pada Java memiliki sifat yang sama sekali berbeda dengan tipe data primitif lainnya. variabel salam berisi String "Selamat". Akan tetapi jika kita mencoba menulis seperti ini Murid mrd99 = new Murid().

kita tidak peduli dengan bagaimana suatu objek disimpan. bukan 3 dan 4 misalnya. Inisialisasi ini dilakukan setiap kali objek PasanganDadu dibuat. Perintah "dadu1 = 3" dan "dadu2 = 4" akan dieksekusi setiap kali objek dibuat.dipakai pada memori heap untuk menempatkan objek tersebut. // Angka pada dadu kedua public void kocok() { // Kocok dadu dengan menggunakan bilangan acak antara 1 dan 6 . Sebagai programmer. dengan potongan kode berikut : class PasanganDadu { public int dadu1 = (int)(Math. Kita bisa memodifikasi kelas PasanganDadu dengan nilai awal acak. // Angka pada dadu pertama public int dadu2 = (int)(Math.random()*6) + 1. akan tetapi kita bisa membuat banyak objek dari kelas ini. yang disebut dengan instansi objek tersebut. kemudian mengisi objek itu dengan variabel instansi. yang melambangkan sepasang dadu. } } // akhir kelas PasanganDadu Variabel instansi dadu1 dan dadu2 diisi dengan nilai awal 3 dan 4. Misalnya. // Angka pada dadu pertama public int dadu2 = 4. yaitu : class PasanganDadu { public int dadu1 = 3. dadu2 = (int)(Math. kelas berikut yang bernama PasanganDadu. seperti variabel lainnya.random()*6) + 1. // Angka pada dadu kedua public void kocok() { // Kocok dadu dengan menggunakan bilangan acak antara 1 dan 6 dadu1 = (int)(Math. objek tersebut memiliki tempat di memori sendiri. Variabel instansi dapat diisi dengan nilai awal pada saat ia dideklarasikan.random()*6) + 1. kita bahkan ingin suatu objek melakukan tugas tertentu untuk pertama kali begitu ia diciptakan. Ingat bahwa kelas PasanganDadu hanya 1. Setiap kali objek dibuat. akan tetapi kita ingin mengatur supaya nilai yang disimpan pada saat objek tersebut dibuat sesuai dengan keinginan kita. Dalam beberapa kasus.random()*6) + 1. Kelas ini memiliki dua variabel instansi yang melambangkan nilai yang ditunjukkan oleh masing-masing dadu dan metode instansi untuk mengocok dadu.

sehingga nilai awalnya adalah null). Bagian ekspresi PasanganDadu() mirip seperti memanggil subrutin. dan protected (static tidak diperbolehkan). Jika variabel instansi tidak kita beri nilai awal. double. mengisi nilai variabel instansi dengan nilai bawaannya. Sifat yang bisa digunakan hanya sifat akses. Bagaimana cara mendefinisikan konstruktor? Konstruktor dideklarasikan mirip dengan deklarasi subrutin.random()*6) + 1. Pada contoh di atas. maka kita harus membuat konstruktor sendiri. Untuk inisialisasi variabel static. Dalam hal ini. Sebetulnya itulah yang terjadi. dengan 3 perkecualian. yang jika kita tidak buat secara khusus. Kita bisa menggunakan perintah apapun seperti pada subrutin biasa. Akan tetapi semua kelas memiliki konstruktor. yaitu public.random()*6) + 1. private. Konstruktor tidak memiliki tipe keluaran (void pun tidak dibolehkan. hal ini tidak mungkin dilakukan. maka setiap objek akan memiliki nilai yang berbeda-beda hasil dari instruksi Math. meletakkannya di memori dan menyimpan alamat objek ini di memori pada variabel dadu. yang disebut konstruktor bawaan. Namanya harus sama dengan nama kelas di mana ia dideklarasikan. yaitu program memanggil subrutin spesial yang dinamakan konstruktor (constructor). Tipe data numerik (int. Variabel instansi juga bisa bertipe suatu objek. (Ingat bahwa String adalah objek. Objek dibuat dengan operator new.random() pada inisialisasi variabel instansi. termasuk memiliki satu atau lebih parameter formal. dan mengembalikan alamat objek yang dibuat di memori. tidak peduli berapa pun banyaknya objek yang dibuat. new PasanganDadu() adalah perintah untuk membuat objek. dadu2 = (int)(Math. Java akan menambahkannya secara otomatis. Di lain pihak. Mungkin Anda heran karena kita tidak melihat adanya subrutin bernama PasanganDadu(). Konstruktor bawaan melakukan hal-hal umum seperti mengalokasi memori. karena hanya ada 1 variabel statik untuk 1 kelas. variabel tersebut bernilai awal null. misalnya program yang ingin menggunakan objek PasanganDadu dapat menggunakan perintah berikut : // deklarasi variabel dan pembuatan objek dilakukan sekaligus PasanganDadu dadu = new PasanganDadu(). dll) memiliki nilai bawaan 0.dadu1 = (int)(Math. maka nilai bawaan akan diberikan secara otomatis. } } // akhir kelas PasanganDadu Karena inisialisasi dilakukan setiap kali objek dibuat. Sebetulnya salah satu alasan untuk menggunakan parameter . konstruktor memiliki blok yang terdiri dari kumpulan perintah seperti pada subrutin. boolean bernilai awal false. Jika kita menginginkan hal lain yang ikut dilaksanakan ketika suatu objek dibuat. dan char bernilai awal karakter dengan kode Unicode 0.

int nilai2) . Java akan membuat konstruktor bawaan apabila tidak ada . mengambil nilai1 dan nilai2 sebagai nilai awal untuk dadu1 dan dadu2 dadu1 = nilai1. Membuat objek baru yang variabel intansinya dadu1 dan dadu2 bernilai 1 dan 2. class PasanganDadu { public int dadu1. // Angka pada dadu kedua public PasanganDadu(int nilai1. PasanganDadu dadu = new PasanganDadu(1. dadu2 = nilai2. Misalnya. dadu2 = (int)(Math.2). Karena sekarang kita telah membuat konstruktor.adalah kita bisa membuat beberapa konstruktor yang menerima data dalam berbagai bentuk.. } } // akhir kelas PasanganDadu Konstruktor dideklarasikan dalam bentuk "public PasanganDadu(int nilai1. } public void kocok() { // Kocok dadu dengan menggunakan bilangan acak antara 1 dan 6 dadu1 = (int)(Math. sehingga objek yang kita buat bisa dinisialisasi dengan cara yang berbeda-beda sesuai dengan kondisi dan kebutuhan dari program yang akan kita buat. int nilai2) { // Konstruktor.".random()*6) + 1. yaitu nilai1 dan nilai2. Misalnya. Konstruktor ini memiliki 2 parameter yang harus diisi ketika konstruktor dipanggil. Dalam hal ini kita buat konstruktor yang menerima 2 nilai sebagai nilai awal dadu. // Angka pada dadu pertama public int dadu2. kita tidak bisa lagi membuat objek dengan perintah "new PasanganDadu()". tanpa tipe keluaran dan dengan nama yang sama dengan nama kelas.. kelas PasanganDadu di atas kita ubah sehingga kita bisa memberi nilai awal sendiri.random()*6) + 1. Ini adalah cara Java mengenal suatu konstruktor dan membedakannya dengan subrutin biasa.

} . // Angka pada dadu kedua public PasanganDadu() { // Isi dadu1 dan dadu2 dengan bilangan acak. karena suatu kelas bisa terdiri dari beberapa konstruktor asalkan parameternya berbeda. dadu2 = nilai2. dengan memanggil metode // kocok() kocok().satupun konstruktor yang didefinisikan.random() * 6) + 1. int nilai2) { // Konstruktor. mengambil nilai1 dan nilai2 sebagai nilai awal untuk // dadu1 dan dadu2 dadu1 = nilai1. // Angka pada dadu pertama public int dadu2. dadu2 = (int) (Math. } public void kocok() { // Kocok dadu dengan menggunakan bilangan acak antara 1 dan 6 dadu1 = (int) (Math. Akan tetapi. } public PasanganDadu(int nilai1. class PasanganDadu { public int dadu1. Sekarang kita akan modifikasi lagi kelas tersebut dengan 2 konstruktor.random() * 6) + 1. maka objek tersebut akan mengisi nilai dadu1 dan dadu2 dengan bilangan acak. kita bisa membuat konstruktor lain di kelas tersebut. yang mana apabila tidak ada parameter yang diberikan.

public class KocokDuaPasangDadu { /** * @param args */ public static void main(String[] args) { PasanganDadu daduPertama = new PasanganDadu(). // pasangan dadu pertama PasanganDadu daduKedua = new PasanganDadu(). // pasangan dadu kedua int jumlahKocokan. teknik seperti ini mempermudah pemecahan masalah dengan mengelompokkannya menjadi ciri dan perilaku suatu objek. // untuk mengitung berapa kali dua pasang dadu // tersebut dikocok int total1. Program lengkapnya bisa diunduh di sini untuk diimport ke dalam Eclipse. // hitung berapa kali dadu kedua muncul jumlahKocokan = 0.kocok().y)". di mana x dan y adalah ekpresi bernilai int. // hitung berapa kali dadu pertama muncul int total2. Kelas ini. do { daduPertama.} // akhir kelas PasanganDadu Sekarang kita bisa memilih bagaimana membuat objek. // kocok dadu pertama . Bagi programmer. Program tersebut tidak lagi harus memanggil fungsi (int)(Math.random()*6) + 1 karena perintah ini sudah diimplementasikan di dalam kelas PasanganDadu. Berikut ini adalah contoh program lain yang menggunakan objek PasanganDadu() untuk menghitung berapa kali kocok akan menghasilkan jumlah nilai yang sama. yaitu dengan "new PasanganDadu()" atau dengan "new PasanganDadu(x. bisa digunakan dalam program lain yang membutuhkan sepasang dadu.

System.out.dadu2.total1 = daduPertama. } } Keluarannya adalah sebagai berikut . System.println("Butuh " + jumlahKocokan + " kocokan hingga pasangan " + " dadu pertama dan kedua berjumlah sama").println("Pasangan dadu pertama berjumlah " + total1).out.dadu1 + daduPertama. jumlahKocokan++.kocok(). // kocok dadu pertama total2 = daduKedua. // hitung jumlahnya System.out.out.println().dadu2. // cetak baris kosong } while (total1 != total2). daduKedua. // hitung jumlahnya System.println("Pasangan dadu pertama berjumlah " + total2).dadu1 + daduKedua.

di sini "parameter" boleh kosong. karena konstruktor tidak dimiliki oleh suatu objek. cukup untuk dipakai oleh objek yang akan dibuat . kita akan simpan hasil keluarannya di dalam suatu variabel. dan bukan metode instansi. dalam bentuk new nama_kelas(parameter). Pertama. Hasil keluarannya adalah alamat memori di mana objek yang baru dibuat tersebut disimpan. Konstruktor mirip dengan subrutin anggota statik. Karena tugasnya membuat objek. komputer memberi daerah pada memori yang tidak digunakan. Bahkan menurut spesifikasi Java. konstruktor bukan anggota suatu kelas sama sekali. Tidak seperti subrutin lain. Seringkali. atau bisa juga hasil keluarannya diberikan ke dalam suatu fungsi sebagai parameter. konstruktor hanya bisa dipanggil melalui operator "new". tetapi bukan subrutin biasa. Hal-hal berikut sangat membantu untuk lebih memahami apa yang dilakukan oleh konstruktor ketika ia dipanggil untuk membuat suatu objek: 1. tetapi dia tidak bisa dideklarasikan "static". maka konstruktor dijalankan sebelum objek dibuat.Konstruktor adalah subrutin. Memanggil konstruktor lebih rumit daripada memanggil subrutin atau fungsi biasa.

4. } . nilai2. Hasil keluarannya adalah referensi ke objek yang baru saja dibuat. } public String getNama() { // Metode untuk mengambil variabel anggota yang bersifat private // misalnya variabel instansi nama return nama. Parameter aktual pada konstruktor (jika ada) akan dievaluasi dan nilainya diberikan kepada parameter formal konstruktor tersebut. 3. nilai3. Jika deklarasi variabel instansi pada kelas memiliki nilai awal tertentu. Referensi objek akan dikembalikan kepada si pemanggil. Komputer akan mengisi variabel instansi objek tersebut dengan nilai bawaannya. // Nama murid public double nilai1.2. } public double hitungRataRata() { // Hitung rata-rata ulangan return (nilai1 + nilai2 + nilai3) / 3. Kita akan tambahkan konstruktor dan juga kita ganti variabel instansi "nama" menjadi bersifat privat. Perintah pada konstruktor (jika ada) akan dilaksanakan. Contoh lain. class Murid { private String nama. Kita bisa gunakan referensi ini untuk mengambil data pada variabel instansi objek tersebut atau memanggil metode instansinya. // Nilai-nilai ujian Murid(String namaMurid) { // Konstruktor objek Murid nama = namaMurid. 5. mari kita ganti kelas Murid pada bagian sebelumnya. maka nilai tersebut akan dimasukkan sebagai nilai awalnya.

setiap kali kita membuat objek. komputer tidak bisa lagi menunjuk kepada objek yang baru dibuat tersebut. isi variabel nama harus diisi dengan perintah terpisah setelah objek dibuat. destruksi (lawan konstruksi yang berarti menghancurkan) objek dilakukan secara otomatis. misalnya selesai melakukan tugas dalam subrutin. Pada baris berikutnya. Di baris pertama. Objek dibuat di dalam memori heap. Pada versi baru di atas. isi variabel mrd diisi dengan null (atau referensi kosong). Dalam kondisi seperti ini. karena ini dideklarasikan pada konstruktornya. Pemulung Memori (Garbage Collector) Hingga saat ini kita hanya berbicara tentang membuat objek. Java menggunakan prosedur yang dinamakan pemulung memori (garbage collector) untuk mengambil memori di mana suatu objek tidak lagi bisa diakses oleh program. Lalu bagaimana menghapus objek? Pada bahasa pemrograman Java. referensi objek baru akan disimpan pada variabel mrd. Atau dengan kata lain. sehingga referensi ke objek tersebut juga hilang? Perhatikan contoh berikut ini. Apa yang akan dilakukan jika variabel tersebut hilang. mrd = null. Murid mrd = new Murid("Joko Susanto"). parameter namaMurid harus disertakan. Masalahnya programmer tidak selalu ingat untuk mengisi nilai nama. karena refernsinya hilang. sehingga referensi ke objek yang baru kita buat menjadi hilang. objek tersebut tidak akan pernah bisa dipakai lagi. maka isi variabel ini tidak bisa diganti dari luar kelas. Sekali objek Murid dibuat. dan karena tidak bisa diakses langsung dari luar. Objek bertipe Murid ini bisa dibuat dengan pernyataan seperti: mrd1 = new Murid("Ahmad Surahmat"). mrd2 = new Murid("Hamid Samsudin") Pada versi aslinya. Ini berarti variabel ini tidak bisa diakses oleh dunia luar secara langsung. Sistem komputer . Contoh keamanan lainnya adalah dengan membuat variabel instansi nama bersifat private. maka namanya tidak bisa diganti selama murid tersebut ada. Dengan demikian potensi bug karena kelalaian programmer dapat dihilangkan dengan mudah.} // akhir kelas Murid Objek bertipe Murid berisi informasi tentang murid tertentu. dan bisa diakses hanya melalui referensi yang disimpan oleh variabel. Variabel ini hanya bisa diambil nilainya dengan metode instansi getNama. Konstruktor kelas ini memiliki parameter bertipe String yaitu nama murid yang akan kita buat.

dan Kelas Abstrak Kelas melambangkan cetak biru objek yang memiliki kesamaan struktuk dan perilaku. pemulung memori menjadi suatu hal yang sangat realistis. Anda mungkin bertanya kenapa tidak semua bahasa pemrograman menggunakan pemulung memori? Dulu. yang mana programmer lupa menghapus objek yang tidak lagi digunakan. Jika kelas B adalah kelas turunan dari kelas A. Ide utama dari pemrograman berorientasi objek -. Suatu objek baru menjadi sampah apabila semua referensi yang merujuk pada objek tersebut hilang. Programmer mungkin tidak sengaja menghapus objek tersebut. Karena Java memiliki pemulung memori. Jika suatu objek telah selesai digunakan. Akan tetapi. pemulung memori membutuhkan waktu pemrosesan yang lama. Dalam beberapa bahasa pemrograman lain. sehingga penggunaannya akan mengurangi kinerja program secara keseluruhan. Biasanya dalam kenyataan sehari-hari. Jika dibiarkan. sangat mudah dilihat bahwa objek Murid telah menjadi sampah. Kemiripan ini diekspresikan dalam bentuk pewarisan dan polimorfisme (perubahan bentuk). Istilah pewarisan berarti suatu kelas bisa mewariskan sebagian atau keseluruhan struktur dan perilaku kelas lain. sangat sulit untuk melacak mana objek sampah dan mana yang ukan. sehingga komputer bisa berhenti total.adalah menciptakan kelas yang memiliki hanya beberapa (tidak semua) struktur dan perilaku. dan sering menimbulkan bug yang tidak terduga. dan sudah digunakan pada beberapa bahasa pemrograman sejak tahun 1960-an.yang membedakannya dari pemrograman tradisional -. Atau bahkan kelas turunan bisa mengubah atau mengganti perilaku kelas supernya. Ini disebut kesalahan pointer tak bertuan.harus bertanggung jawab terhadap pengaturan memori. Pewarisan. programmer diharuskan untuk mengatur sampahnya sendiri. kesalahan seperti itu tidak mungkin terjadi. dan ditambah dengan kecepatan komputer yang makin tinggi. Kelas menentukan struktur suatu objek melalui variabel yang terkandung dalam setiap objek. Akan tetapi riset terbaru telah menemukan teknik pemulungan memori yang lebih canggih. dan kesalahannya akan fatal apabila objek yang akan diakses tak lagi berada di alamat memori tersebut. Pada contoh di atas. Berterima kasihlah kepada Java. Hubungan antara kelas turunan dan kelas super sering dilukiskan dalam bentuk diagram di mana kelas turunan digambarkan di bawah kelas supernya. Tipe kesalahan lain adalah kebocoran memori. Pemulung memori sudah dibicarakan sejak lama. maka kita bisa juga menyebut kelas A adalah kelas super dari kelas B. untuk melacak objek yang menjadi "sampah". bukan programmer. Ini akan berakibat pada penuhnya memori dengan sampah yang tidak bisa lagi diakses karena referensinya telah hilang. maka lambat laun seluruh memori komputer akan habis. dan dihubungkan dengan garis penghubung dengan tanda segitiga yang diletakkan di dekat kelas supernya. mencoba mengatur penggunaan memori secara manual sangat sulit. dan menentukan perilaku melalui metode instansi yang merupakan perilaku suatu objek. . Kelas turunan bisa memiliki struktur atau perilaku tambahan dari kelas supernya. Polimorfisme. meskipun ada variabel lain yang masih merujuk pada objek tersebut. mungkin akan ada beberapa variabel yang masih menyimpan referensi ke objek tersebut.

C. Pewarisan juga bisa dilakukan beberapa kali. kita bisa menyatakan bahwa kelas tersebut merupakan kelas turunan dari kelas lain. sehingga kelas E adalah "cucu" dari kelas A. } Beberapa kelas dapat menurunkan kelas yang sama. kelas B. . ketika kita membuat suatu kelas. yaitu diwariskan dari satu kelas super yang sama. buyut. Kelas E masih bisa disebut turunan dari kelas A. Struktur dan perilaku kelas super ini akan dimiliki oleh masing-masing turunannya. . // tambahan atau perubahan . dan D adalah kelas saudara. dan seterusnya. atau suatu kelas bisa memiliki cucu. Pada diagram berikut. Jika kita buat kelas yang bernama "B" dan kita ingin kelas ini menjadi kelas turunan dari kelas "A".Dalam bahasa Java. Kelas-kelas turunan ini masing-masing disebut kelas saudara. walaupun bukan merupakan turunan langsungnya. // struktur dan perilaku dari kelas A . kita akan tulis dalam bentuk : class B extends A { . kelas E merupakan kelas turunan kelas D. Pada diagram.

Orang pemilik. Kelas-kelas ini bisa dideklarasikan dalam Java dalam bentuk class Kendaraan { int nomorPolisi.Mari kita buat sebuah contoh. Program tersebut memiliki kelas yang dinamakan Kendaraan yang melambangkan semua jenis kendaraan bermotor. Ada 3 kelas turunannya yaitu Mobil. } class Truk extends Kendaraan { . } . . Kelas Mobil misalnya memiliki variabel jumlahPintu. Kita akan membuat program yang berhubungan dengan kendaraan bermotor. . dan motor. . // (anggap kelas Orang telah dibuat sebelumnya) void gantiPemilik(Orang pemilikBaru) { . Variabel dan metode instansi ini bisa digunakan oleh segala jenis kendaraan bermotor. kelas Truk memiliki variabel jumlahRoda. yang meliputi mobil. Truk dan Motor yang akan menyimpan variabel dan metode khusus untuk setiap jenis kendaraan. . . dan kelas Motor memiliki variabel jumlahTak. } class Mobil extends Kendaraan { int jumlahPintu. . . truk. Kelas Kendaraan memiliki variabel instansi seperti nomorPolisi dan pemilik dan metode instansi yang bernama gantiPemilik.

Dengan deklarasi seperti ini. } Anggap mobilku adalah variabel dengan tipe Mobil akan dideklarasikan dan diinisialisasi dengan pernyataan berikut Mobil mobilku = new Mobil(). variabel kendaraanku berisi referensi ke objek Kendaraan. Dalam arti objek yang memiliki tipe Mobil atau Truk atau Motor juga secara otomatis objek bertipe Kendaraan. maka program akan bisa mengakses mobilku. karena jumlahPintu adalah variabel instansi dari kelas Mobil. Fakta penting berikutnya : Variabel yang dapat diisi referensi ke objek suatu kelas A juga dapat diisi referensi ke objek kelas turunan dari kelas A. atau dengan kata lain perintah berikut adalah valid Kendaraan kendaraanku = mobilku.gantiPemilik() Dalam dunia nyata mobil. } class Motor extends Kendaraan { int jumlahTak. maka mobil ini juga memiliki stuktur dan perilaku dari kendaraan. .jumlahPintu. // 2-tak atau 4-tak .pemilik.int jumlahRoda. mobilku.nomorPolisi. . Objek akan "mengingat" . Akan tetapi karena kelas Mobil merupakan turunan dari kelas Kendaraan. yang kebetulan merupakan instansi dari kelas turunannya. . Efek praktis dari penyataan ini adalah. Setelah pernyataan di atas. Artinya program juga bisa mengakses mobilku. objek dengan tipe Mobil dapat diisi ke dalam variabel bertipe Kendaraan. . yaitu kelas Mobil. truk dan motor memang kendaraan (bukan hanya pada program). . atau bahkan juga perintah berikut Kendaraan kendaraanku = new Mobil(). dan menjalankan metode mobilku.

if (kendaraanku instanceof Mobil) System. kita bisa menggunakan casting.println("Nomor polisi: " + kendaraanku.out.println("Jumlah tak: " + sm.out.out. System.. } else if (kendaraanku instanceof Motor) { System. Misalnya if (kendaraanku instanceof Mobil) { .bahwa yang disimpan dalam variabel tersebut adalah objek bertipe Mobil. pernyataan berikut tidak bisa dilakukan mobilku = kendaraanku. bukan Kendaraan. mari kita buat program untuk menggambar suatu bentuk geometri pada layar. oval. Mobil m = (Mobil)kendaraanku. dan kotak bersudut lingkar dengan berbagai warna. Motor sm = (Motor)kendaraanku . Informasi tentang objek apa yang disimpan pada memori ikut disertakan bersama objek tersebut. } Lihat bahwa untuk setiap jenis objek.println("Jumlah roda: " + t.println("Jumlah pintu: " + m. komputer akan menguji satu per satu tipe objek yang disimpan dalam kendaraanku.out.println("Data Kendaraan:"). } else if (kendaraanku instanceof Truk) { System.out.out. System. sehingga variabel yang bertipe Kendaraan akan tahu dengan pasti tipe objek yang dirujuknya.. Atau kita juga bisa mengakses ((Mobil)kendaraanku). Jika kendaraanku[code] merujuk pada objek bertipe Truk maka casting [code](Mobil)kendaraanku akan menampilkan pesan kesalahan. Contoh lain. Jadi kita bisa gunakan perintah mobilku = (Mobil)kendaraanku. Kita juga dapat menguji jenis objek yang disimpan suatu variabel dengan menggunakan operator instanceof. Truk t = (Truk)kendaraanku .out.jumlahPintu. Misalnya bentuk geometri tersebut terdiri dari persegi panjang.jumlahRoda).out.println("Jenis kendaraan: Mobil").println("Jenis kendaraan: Truk"). karena kendaraanku bisa bertipe objek lain seperti Truk atau Motor. dan kita ingin mencetak informasi yang sesuai dengan suatu kendaraan. untuk memberi tahu komputer untuk memperlakukan variabel kendaraanku memiliki tipe Mobil. Misalnya: System. System. System. .println("Jenis kendaraan: Motor"). Kebalikannya.jumlahPintu). } menguji apakah objek yang dirujuk pada variabel kendaraanku merupakan objek bertipe Mobil.nomorPolisi). Apabila kita tahu persis bahwa kendaraanku bertipe Mobil. Mari kita gunakan kelas ini dalam program.jumlahTak).

dengan warna baru } void gambar() { // metode untuk menggambar ? ? ? // perintaha apa yang harus diletakkan di sini? } . setiap bentuk digambar dengan cara berbeda. ini berarti setiap kelas turunan dari kelas BentukGeometris memiliki metode gambar() sendiri-sendiri. // gambar ulang bentuk geometris ini. Kelas BentukGeometris memiliki variabel instansi warna.awt) void setWarna(Color warnaBaru) { // Metode untuk mengganti warna warna = warnaBaru. kita bisa jawab dengan : Komputer akan menjalankan perintah gambar() dengan meminta bentuk tersebut untuk menggambar sendiri. Lalu bagaimana komputer tahu bagaimana menggambar bentuk tersebut jika metode gambar() dipanggil? Mudahnya. Ketiga kelas tersebut memiliki kelas super yang sama yang disebut BentukGeometris. . Metode setWarna() dapat digunakan oleh semua bentuk. Untuk mengganti warna kita bisa mengganti variabel instansi warna pada kelas ini. . // metode atau variabel lain } class Oval extends BentukGeometris { void gambar() { . kemudian menjalankan metode instansi gambar() untuk menggambar bentuk tersebut dengan warna baru: class BentukGeometris { Color warna. // Warna suatu bentuk geometri // (Kelas Color diimport dari paket java. Masalahnya. . yaitu : class PersegiPanjang extends BentukGeometris { void gambar() { . lokasi. .Kelas yang akan kita buat adalah PersegiPanjang. Oval. dan ukuran. . dan KotakLingkar. // ganti nilai variabel instansi gambar(). Dalam prakteknya. // variabel dan metode instansi lain } // akhir kelas BentukGeometris Sekarang metode gambar() mungkin menjadi serba salah. Setiap objek bentuk tahu apa yang harus dilakukan untuk menggambar dirinya. // perintah untuk menggambar persegi panjang } . .

// perintah untuk menggambar kotak bersudut lingkar } . dia akan tahu bagaimana merespon pesan tersebut. . Kita sebut metode gambar() bersifat polimorfis. Maka akan sangat mungkin perintah gambarku. tergantung pada objek yang dirujuknya. Pernyataan "gambarku. Dari sudut pandang ini. Mungkin akan lebih mudah dimengerti jika kita ganti bahasanya : Dalam PBO. . Suatu saat di tengah program. Polimorfisme juga berarti bahwa beberapa objek dapat merespon suatu pesan dengan cara yang berbeda-beda.} . . Karena objek tersebut tahu jenis objeknya sendiri.gambar() dipanggil berulang-ulang tetapi dengan objek yang berbeda-beda. yaitu dengan mengirim pesan. Pesan tersebut bergantung pada siapa yang menerima pesan tersebut. misalnya segitiga. karena kita tidak pernah tahu isi variabel gambarku pada suatu saat tertentu. Polimorfisme adalah fitur utama dalam pemrograman berorientasi objek. misalnya PersegiPanjang.gambar(). Oval. apa yang harus kita isi pada metode gambar() di kelas BentukGeometri? . Salah satu keindahan dari poliformisme adalah kita bisa membuat kode program tanpa harus mengetahui persis apa yang akan dilakukan program saat kita menulis program tersebut. . maka kita cukup menulis kelas turunan baru dan membuat metode gambar() sendiri." adalah pesan yang dikirim ke objek gambarku. Suatu metode disebut polimorfis jika aksi yang dilakukan oleh suatu metode berbeda-beda tergantung pada objek aktual pada saat metode itu dijalankan. metode gambar() yang sesuai dengan objek yang menerima pesan akan dilaksanakan. Objek tersebut merespon pesan tersebut dengan melaksanakan metode yang sesuai. Kita tidak akan bisa menebak metode apa yang akan dipanggil pada suatu saat hanya dengan membaca program tersebut. maka metode gambar() akan dijalankan tergantung pada isi variabel gambarku saat itu. atau KotakLingkar. . atau KotakLingkar. program akan tahu jika kita beri perintah "gambarku. objek merupakan sesuatu yang memiliki perilaku aktif.gambar() dijalankan. Dengan kata lain. ." dengan cara yang sama. Ketika suatu objek. Ketika program dijalankan. variabel ini bisa merujuk pada objek dengan bertipe PersegiPanjang.gambar(). .gambar()" maka metode gambar() pada kelas segitiga akan dijalankan apabila gambarku menunjuk pada objek yang memiliki kelas segitiga. Oval. komputer akan selalu mengeksekusi perintah "gambarku. Pertanyaannya. . Secara otomatis. // metode atau variabel lain class KotakLingkar extends BentukGeometris { void gambar() { . // metode atau variabel lain } Jika gambarku adalah variabel bertipe BentukGeometri. Polimorfisme dianggap sebagai sifat yang natural jika dilihat dari sudut pandang ini. // perintah untuk menggambar oval } . Jika kita ingin menambah objek lain. yaitu sesuatu yang bisa mengirim dan menerima pesan. isi variabel gambarku akan berubah-ubah. Misalnya perintah gambar() berada dalam suatu perulangan yang dijalankan berkalikali. memanggil metode sering disebut juga dengan mengirim pesan kepada suatu objek. harus menggambar dirinya sendiri. jika perintah gambarku.

gambar(). Kita bisa menyebut kelas BentukGeometri merupakan kelas abstrak. misalnya PersegiPanjang. . yaitu kelas bawaan yang sudah didefinisikan dalam paket java. Akan tetapi metode ini ada untuk memberi tahu komputer bahwa semua kelas turunannya mengerti dan bisa menjalankan metode gambar(). maka kelas tersebut otomatis memiliki kelas super Object. void setWarna(Color warnaBaru) { // metode untuk mengganti warna suatu bentuk warna = warnaBaru. Untuk metode abstrak. BentukGeometri dan metode gambar() secara sematik merupakan kelas dan metode abstrak. blok perintahnya diganti dengan titik koma (. Apabila kelas tersebut telah direalisasikan dalam suatu bentuk. itu harus ada karena metode ini dibutuhkan untuk memanggil metode setWarna() pada kelas BentukGeometri. Kelas Object adalah satu-satunya kelas yang tidak memiliki kelas super. Intinya kelas BentukGeometri adalah kelas abstrak. dan hanya digunakan untuk membuat kelas turunan. barulah objek tersebut bisa menggambar sesuatu. perintah . kita bisa menyebut metode gambar() pada kelas BentukGeometri merupakan metode abstrak. karena metode ini bukan untuk dipanggil.). Metode ini harus diimplementasikan secara detail pada kelas turunannya. apabila di dalam kelas ini tidak ada metode yang bernama gambar().lang. Dalam Java. // metode abstrak yang harus diimplementasikan // pada kelas turunannya . abstract class BentukGeometri { Color warna. // variabel dan metode instansi lainnya } // akhir kelas BentukGeometri Setelah kita buat seperti ini. atau dengan kata lain setiap kelas merupakan turunan dari kelas lain. // ganti isi variabel instansi warna gambar(). Kelas abstrak adalah kelas yang tidak bisa digunakan untuk membuat suatu objek. Perhatikan contoh berikut.Jawabannya: kosongkan saja. // menggambar kembali suatu bentuk dengan warna baru } abstract void gambar(). Program kita akan menampilkan pesan kesalahan jika kita berikan perintah gambarku. Demikian juga. . Kita juga bisa memberi tahu komputer secara langsung dengan memberi sifat "abstract" pada definisinya. setiap kelas yang kita buat akan memiliki kelas super. Jika kita tidak memberi kelas supernya (melalui operator extends). karena gambarku bertipe BentukGeometri. Kelas abstrak hanya ada untuk mengekspresikan sifat umum yang dimiliki oleh kelas-kelas turunannya. kita tidak bisa lagi membuat objek langsung dari kelas BentukGeometri. Lalu kenapa kita harus mendeklarasikan metode gambar() di kelas BentukGeometri? Jawabannya. karena tidak ada cara untuk menggambar BentukGeometri. Jadi dengan demikian.

n++) { BentukGeometri bg = (BentukGeometri)kumpulanGambar.gambar(). terutama bagi programmer yang baru belajar dan bekerja dengan objek. sintaksnya adalah dalam bentuk class kelas_turunan extends kelas_yang_sudah_ada { .".. ArrayList akan dibahas kemudian dalam topik tentang struktur data dan algoritma. Misalnya. dan sebetulnya kontainer ini bisa menampung objek apa saja. } Penutup Dalam pemrograman sehari-hari. . yang disesuaikan dengan situasi dan kondisi permasalahan yang kita hadapi.remove(gambarku). } sama artinya dengan class Kelasku extends Object { . Jumlah obejk dalam kumpulanGambar dapat diubah dengan perintah "kumpulanGambar. yaitu dengan : for (int n = 0. Kelas Object adalah kelas yang paling abstrak dari kelas-kelas lainnya. n < kumpulanGambar. Suatu objek dengan tipe BentukGeometri misalnya gambarku dapat ditambahkan ke dalam kumpulan ini dengan menggunakan perintah "kumpulanGambar. // tambahan atau perubahan variabel dan metode instansi } Kita akan lihat nanti bahwa banyak kelas-kelas standar pada Java yang digunakan hanya sebagai kelas dasar yang untuk dikembangkan lebih jauh oleh kita sebagai programmer .ArrayList yang merupakan kumpulan Objects. Juga kita bisa mengambil gambar ke-n dari dalam kumpulanGambar dengan perintah "kumpulanGambar.util. kita bisa gunakan perintah gambarku = (BentukGeometri)kumpulanGambar.get(n). sehingga untuk mengambil objek ke-n yang kemudian kita letakkan dalam variabel bertipe BentukGeometri. Kita dapat juga membuat program untuk menampung semua BentukGeometri yang telah digambar di layar dalam kontainer ArrayList. . Katakan misalnya kita ingin menggambar semua objek dengan berbagai tipe di dalam kumpulan tersebut.". bukan hanya BentukGeometri.. Kita bisa membuat kelas baru yang merupakan turunan kelas yang sudah ada.. dan bisa diperbanyak ketika objek baru ditambahkan.get(n). penurunan kelas akan sering digunakan.size(). Gambar tersebut dapat dibuang dari dalam kumpulan dengan perintah "kumpulanGambar.class Kelasku { . Salah satunya adalah untuk memperluas kegunaan suatu kelas. Java memiliki kelas standar java. kita bisa gunakan perulangan for sederhana (sekaligus memberi contoh betapa indagnya PBO dan polimorfisme).get(n). menambah beberapa variabel dan metode instansi baru. Secara umum. bg. yaitu dengan operator extends seperti dijelaskan sebelumnya pada bagian ini.size()". Objek yang dapat ditampung pada dasarnya adalah semua objek dari beragam kelas. Kelas ini digunakan untuk menampung kumpulan objek. Kelas Objek memiliki sifat-sifat umum yang dapat digunakan oleh semua objek. Kelas Object digunakan dalam beberapa kasus di mana kumpulan objek yang sangat umum ingin diolah. tak ditentukan jumlahnya. Milsanya ArrayList kita bernama kumpulanGambar. Perlu diingat bahwa metode tersebut akan mengembalikan objek bertipe Object bukan BentukGeometri. Artinya suatu obek yang merupakan kelas apapun dapat direferensikan oleh variabel bertipe Object. } Semua kelas akan merupakan turunan langsung atau tidak langsung dari kelas Object."..add(gambarku).

Jika metode suatuMetode() adalah metode instansi pada suatu objek. } . .namaAnggota". } Dalam konstruktor di atas.this dan super Meskipun ide dasar dari pemrograman berorientasi objek merupakan konsep yang cukup sederhana dan jelas. misalnya kita sedang menulis metode instansi di suatu kelas. kita harus menggunakan nama objek yang diciptakan dari kelas tersebut. maka ia harus dipanggil dengan nama lengkapnya dalam bentuk "namaKelas. Ketika komputer menjalankan perintah tersebut. merujuk pada "objek ini" yaitu objek di mana metode sedang dijalankan. Akan tetapi. akan tetapi pengenalan tentang hal detail ini sangat berguna paling tidak sebagai bahan referensi. Bagian ini dan bagian berikutnya akan berbicara tentang hal-hal detail. Untuk digunakan di kelas lain. membuat murid dengan nama yang diberikan this. variabel instansi nama disembunyikan oleh parameter formal yang bernama sama. akan tetapi untuk memahaminya dengan baik kita membuthkan lebih banyak waktu. bukan kelas. Anggota instansi juga memiliki nama lengkap akan tetapi ingat bahwa anggota instansi dimiliki oleh objek. misalnya suatu variabel instansi bisa digunakan langsung oleh metode instansi di kelas yang sama. // Nama murid public Murid(String nama) { // Konstruktor. Salah satu kegunaaan this adalah pada konstruktor. Variabel dan metode instansi juga bisa digunakan langsung di dalam kelas tersebut.x adalah nama lengkap variabel tersebut jika dipanggil dari dalam objek yang sama. maka this.out" adalah variabel anggota statik dengan nama "out" di dalam kelas "System".nama = nama. Maksudnya. Sayangnya. misalnya "System. Sehingga untuk memanggil suatu anggota instansi. Bagaimana caranya kita memanggil anggota instansi kelas yang sama jika kita belum tahu nama objek apa yang diciptakan dari kelas ini? Java memiliki variabel spesial yang dinamakan "this" yang bisa digunakan untuk kasus di atas.namaAnggota. Variabel spesial this dan super Anggota statik suatu kelas bisa digunakan langsung di dalam kelas tersebut. // Variabel dan metode lain. Jika x adalah variabel instansi dalam suatu objek. banyak sekali detail yang harus diulas di luar konsep dasarnya. . variabel instansi masih tetap bisa dipanggil dengan nama . yang tidak perlu dikuasai dalam waktu singkat. this. misalnya karena nama anggota tersebut disembunyikan oleh variabel lokal yang namanya sama. maka this. Akan tetapi. komputer akan mengganti variabel this dengan objek yang berjalan pada saat itu. Kita bisa menggunakan nama lengkap kelas tersebut di manapun. misalnya : public class Murid { private String nama.suatuMetode() bisa digunakan untuk memanggil metode tersebut dari objek yang sama. Variabel ini digunakan pada suatu objek untuk memanggil metode atau variabel instansi pada objek yang sama. bahkan dari dalam kelas yang sama. dalam bentuk namaObjek.

. termasuk metode gambar() . Variabel super bisa digunakan untuk mengakses metode aslinya yang didefinisikan di kelas supernya. kita bisa menggunakan perintah "System. Pokoknya. Misalnya karena kita mengimplementasikan fungsi lain pada kelas turunan dengan nama yang sama (dalam kaitannya dengan polimorfisme. yang dalam hal ini sama dengan kelas supernya. // Panggil metode kocok() di kelas PasanganDadu gambar(). Dalam bahasa pemrograman. Cara ini merupakan cara yang lazim. Variabel super hanya mengacu pada bagian objek sebelum ia ditambah atau dimodifikasi. Misalnya. Ada lagi kegunaan lain dari this. Kita bisa menggunakan nama parameter formal yang sama persis dengan variabel instansinya. Ketika kita membuat metode baru pada kelas turunan yang memiliki nama dan jenis parameter yang sama dengan metode pada kelas supernya. Java juga memiliki variabel spesial yang dinamakan "super" untuk digunakan dalam metode instansi. Kemudian kita akan membuat kelas turunan yaitu DaduGrafis yang berfungsi untuk menggambar dadu pada layar. Suatu kelas bisa ditambah atau dimodifikasi dari kelas turunannya.lengkapnya. super mengacu pada objek di mana metode tersebut berada. // Gambar ulang dadu } . kita bisa melakukan segala hal seperti layaknya variabel kecuali mengganti isinya. Ketika kita sedang menulis metode instansi. dan kelas tersebut memiliki metode instansi bernama suatuMetode(). kemudian menambahkan instruksi lain pada kelas turunannya.kocok().". bukan menggantinya secara keseluuruhan. Alasan mengapa Java memiliki variabel super adalah karena banyak hal yang mungkin tersembunyi pada kelas turunan. Pernyataan super. Atau kita ingin mengisi nilai this ke dalam variabel lain.out. atau dengan kata lain bentuk aslinya sebelum dia diturunkan. kita memiliki kelas PasanganDadu yang memiliki metode kocok. kemudian menggambarnya di layar super.nama. metode dari kelas super akan disembunyukan. akan tetapi ia merupakan bagian dari kelas super dari objek tersebut.println(this). kita bisa menggunakan this sebagai parameter aktualnya. Kita bisa tulis definisi kelas DaduGrafis dalam bentuk : public class DaduGrafis extends PasanganDadu { public void kocok() { // Mengocok dadu. dengan tambahan perintah untuk menggambar dadu tersebut di layar. Java akan menampilkan pesan kesalahan sintaks. Misalnya kita akan menulis suatu kelas. artinya kita tidak perlu mengganti nama parameter formal dengan nama lain agar namanya tidak bentrok dengan nama salah satu variabel instansinya. kita ingin memberikan objek sebagai parameter aktual. kita ingin mencetak suatu objek sebagai string. Metode baru bisa menggunakan super untuk menjalankan instruksi pada kelas supernya.suatuMetode() berarti menjalankan suatuMetode() pada kelas supernya. Kegunaan utama dari super biasanya untuk memperluas kegunaan metode yang sudah ada. Metode kocok() dalam DaduGrafis harus melakukan apa yang dilakukan oleh PasanganDadu. this. Misalnya. . // Metode dan variabel lain. Jika tidak ada metode sutuMetode() pada kelas supernya. metode ini menimpa (override) metode dari kelas supernya. Variabel super digunakan dalam kelas turunan. misalkan). Dalam hal ini.

Hal ini mungkin menjadi masalah jika konstruktor pada kelas supernya melakukan banyak tugas. Di baris pertama konstruktor baru kita di kelas turunannya. Jika kita ingin konstruktor tersebut pada kelas turunannya. Cara yang paling mudah adalah menggunakan super. dan Detail Lain Beberapa bahasa pemrograman berorientasi objek.} Dengan cara ini kita bisa memperluas apa yang dilakukan oleh metode kocok() pada kelas supernya tanpa mengetahui dengan detail apa yang dilakukan langkah per langkah di kelas supernya. // Lakukan inisialisasi grafis // untuk digunakan pada kelas DaduGrafis } .4). Artinya kita harus mengulang kembali menuliskan semua instruksi pada kelas supernya di kelas turunan yang baru. misalnya apabila tidak ada kode sumbernya. Maka kita bisa membuat konstruktor pada kelas DaduGrafis seperti : public class DaduGrafis extends PasanganDadu { public DaduGrafis() { // Konstruktor kelas ini super(3. misalnya C++. maka Java akan membuat konstruktor standar tanpa parameter apa-apa. membolehkan suatu kelas memiliki dua atau lebih kelas super. variabel dan metode instansi lain . . . Konstuktor pada Kelas Turunan Konstruktor tidak bisa diturunkan. maka kita harus membuat kembali konstruktor tersebut di kelas yang baru. } Antar Muka (interface). Hal ini disebut pewarisan ganda (multiple inheritance). // Panggil konstruktor dari kelas PasanganDadu // dengan parameter 3 dan 4 inisialisasiGrafis(). Misalnya kelas PasanganDadu memiliki konstruktor yang memiliki dua parameter bertipe int. Sintaksnya sedikit aneh dan membingungkan. Kelas Bertingkat. dan hanya bisa digunakan untuk satu situasi saja : Sintaksnya mirip seperti memanggil subrutin super (meskipun sebenarnya super bukan subrutin dan kita tidak bisa memanggil konstruktor seperti kita memanggil subrutin biasa). Masalahnya akan lebih rumit jika kita tidak mengetahui sama sekali apa yang dilakukan kelas supernya. sedangkan kelas F memiliki 3 kelas super. Pada ilustrasi berikut. kita bisa menggunakan super untuk memanggil konstruktor kelas supernya. Jika tidak. kelas E memiliki kelas super A dan B. // Konstruktor. konstruktor pada kelas supernya tidak termasuk bagian yang diturunkan. artinya jika kita membuat kelas turunan dari suatu kelas.

harus mengisi implementasi metode gambar() ini. kata interface adalah kata kunci yang memiliki arti tambahan. class Garis implements Gambar { public void gambar(Graphics g) { . yaitu interfaceGambar. Berikut adalah contoh interface Java sederhana : public interface Gambar { public void gambar(Graphics g). yaitu dalam konteks umum tentang kotak hitam dan subrutin. . } Deklarasi di atas mirip dengan definisi suatu kelas. Dalam Java. Suatu interface dalam hal ini adalah antar muka yang terdiri dari subrutin tanpa implementasi apa-apa. Suatu subrutin juga memiliki implementasi : yaitu blok yang berisi perintah yang akan dijalankan ketika subrutin ini dipanggil. Informasi ini dibutuhkan jika kita ingin memanggi subrutin tersebut. Java memiliki fitur lain yang bisa digunakan seperti halnya pewarisan berganda. . Akan tetapi. yaitu antar muka (interface). // variabel dan metode lain } . Misalnya. Kita telah mengenal istilah "antar muka" sebelumnya. jenis keluarannya. // perintah untuk menggambar garis } . jumlah dan tipe parameternya. Suatu kelas yang mengimplementasi interface ini. Antar muka suatu subrutin terdiri dari nama. Desainer Java ingin menjaga agar bahasa Java tetap sederhana. . akan tetapi isi metode gambar() dikosongkan. .Pewarisan ganda seperti ini tidak diperbolehkan pada Java. Suatu kelas dapat mengimplementasi suatu interface dengan memberikan kode detail pada setiap subrutin yang ditulis pada interface tersebut. Tentunya kelas tersebut juga bisa memiliki variabel dan metode lain. dan mereka merasa pewarisan ganda ini sangat kompleks dengan keuntungan yang tidak begitu besar.

akan tetapi suatu variabel dapat bertipe suatu interface. yaitu kelas yang hanya digunakan untuk membuat kelas lain.gambar(g).. // Deklarasi variabel dengan tipe Gambar. jika Gambar adalah suatu interface. Misalnya class LingkaranBerwarna extends Lingkaran implements Gambar. Seperti kelas abstrak. suatu kelas bisa menurunkan kelas lain dan mengimplementasikan satu atau lebih antar muka sekaligus. akan tetapi interface mirip dengan kelas. // memanggil metode gambar() dari kelas LingkaranBerwarna . // Sekarang gambarku berisi objek dengan // kelas LingkaranBerwarna gambarku. meskipun kita tidak bisa membuat objek dari interface. Perlu diingat bahwa hanya menambah metode gambar() saja tidak cukup. maka kita bisa menulis kode seperti : Gambar gambarku. Objek yang diciptakan dari kelas tersebut akan memiliki metode gambar(). // gambarku berisi objek dengan kelas Garis gambarku. akan tetapi suatu kelas bisa mengimplementasikan lebih dari suatu antar muka. Suatu kelas bisa menurunkan hanya satu kelas lain. BerisiWarna { . } Intinya adalah meskipun interface bukan kelas. // memanggil metode gambar() dari kelas Garis gambarku = new LingkaranBerwarna(). Misalnya.gambar(g). suatu interface mirip seperti kelas abstrak. Definisi kelas yang ingin mengimplementasikan suatu interface harus menulis "implements Gambar" dalam definisi kelasnya.Kelas apapun yang mengimplementasi antar muka Gambar[code] harus memberikan detail apa yang akan dilakukan oleh metode [code]gambar(). bukan untuk membuat objek. Subrutin pada suatu interface merupakan metode abstrak yang harus diimplementasikan pada kelas kongkrit yang mengimplementasikan interface tersebut.. dan jika Garis dan LingkaranBerwarna adalah kelas yang mengimplementasikan Gambar. Sebenarnya. // Variabel ini bisa diisi objek yang // mengimplementasi interface Gambar gambarku = new Garis().

Dari semuanya. Jika tidak dideklarasikan sebagai private. namanya harus jelas mencantumkan nama kelas induknya. Kita biasanya tidak perlu menulis interface kita sendiri hingga program kita menjadi sangat kompleks.Garis. tipe data bisa berupa kelas.gambar(g)" boleh ditulis karena gambarku adalah variabel dengan tipe Gambar. Kelas bagian dalam ini bisa memiliki nama atau anonim (tanpa nama). akan tetapi ingat akan konsekuensi kerumitannya apabila kita membuat terlalu banyak tingkatan). Kelas bagian dalam yang memiliki nama tampak seperti kelas biasa.Variabel dengan tipe Gambar boleh merujuk pada kelas apapun yang mengimplementasikan antar muka Gambar. dan setiap objek bertipe Gambar pasti memiliki metode gambar(). Kelas kecil ini menjadi bagian dari suatu kelas besar yang bisa melakukan hal-hal kompleks lainnya. Kelas tersebut bisa digunakan di dalam kelas induknya untuk membuat objek seperti biasa. atau salah satu dari 8 tipe data primitif. (Kelas bagian dalam ini juga bisa memiliki kelas bagian dalam yang lain. suatu kelas bernama ModelRangkaKawat melambangkan kumpulan garis dalam ruang 3 dimensi. Catatan bahwa tipe data merupakan sesuatu yang biasa digunakan untuk mendeklarasikan variabel. Akan tetapi kadang-kadang kelas-kelas kecil ini sering bermanfaat dan penting. Maka dari luar kelas ModelRangkaKawat. Akan tetapi ada beberapa interface yang sudah disediakan oleh Java yang mungkin bisa digunakan atau diimplementasi dalam program kita. Kelas Bertingkat Suatu kelas merupakan blok bangunan suatu program. interface. makan kelas tersebut juga bisa digunakan dari luar kelas induknya. Dalam Java. atau sebagai tipe keluaran suatu fungsi. Misalnya. . Kelas bertingkat statik merupakan bagian dari struktur statik dari kelas yang menaunginya. Pada Java. sehingga kelas-kelas kecil ini tidak perlu berdiri sendiri. kelas bertingkat atau kelas bagian dalam adalah kelas yang ditulis di dalam definisi kelas lain. Kelas kecil ini misalnya berguna untuk mendukung operasi yang akan dikerjakan oleh kelas besarnya. yang melambangkan suatu ide beserta data dan perilaku yang dimilikinya. tetapi ia ditulis di dalam kelas lain. Pernyataan di atas seperti "gambarku. Tipe data juga digunakan untuk memberikan tipe suatu parameter pada subrutin. kelas bagian dalam yang memiliki nama bisa berupa kelas statik atau kelas non-statik. hanya kelas yang bisa digunakan untuk membuat objek baru. Kadang-kadang kita mungkin berasa sedikit aneh untuk membuat kelas kecil hanya untuk menggabungkan beberapa data. Jika digunakan dari luar kelas induknya. kelas Garis akan dipanggil sebagai ModelRangkaKawat. Untungnya Java membolehkan kita untuk membuat kelas di dalam kelas lain. Misalnya kelas ModelRangkaKawat memiliki kelas bertingkat statik yang bernama Garis yaitu sebuah garis. Seperti komponen lain dalam suatu kelas. Mirip seperti komponen statik dari suatu kelas : kelas bertingkat statik adalah bagian kelas di mana kelas tersebut mirip dengan variabel anggota statik lainnya di dalam kelas tersebut.

z2. Meskipun definisi kelas Garis berada di dalam ModelRangkaKawat.z1) // ke titik (x2. . Hal ini juga berlaku untuk kelas bertingkat non-statik seperti juga bagian kelas non-statik lainnya. akan tetapi kelas bertingkat non-statik berkaitan dengan suatu objek. double x2. Anggota non-statik dari suatu kelas sebenarnya bukan merupakan bagian dari kelas itu.Kelas ModelRangkaKawat dan kelas bagian dalamnya dapat dituliskan seperti berikut : public class ModelRangkaKawat { . Mungkin ini juga motivasi sebagian orang untuk membuat kelas bertingkat. .Garis()" harus digunakan.y2. termasuk ke anggota private. bukan kelas induknya. perintah "new ModelRangkaKawat. // anggota lain kelas ModelRangkaKawat } // akhir kelas ModelRangkaKawat Di dalam kelas ModelRangkaKawat. } // akhir kelas Garis . pada prakteknya. dua file kelas akan dibuat.class Kelas bertingkat yang tidak statik. Kelas bertingkat statik memiliki akses penuh kepada anggota dari kelas induknya. tidak jauh berbeda dengan kelas bertingkat statik. . . objek Garis bisa dibuat dengan konstruktor "new Garis()". z1. Nama file kelas Garis akan menjadi ModelRangkaKawat$Garis.y1. Ketika kita mengkompilasi definisi kelas di atas.z2) dalam ruang 3-dimensi double x1. y1. Di luar kelas. . // anggota lain kelas ModelRangkaKawat static public class Garis { // Melambangkan garis dari titik (x1. y2. karena kelas bagian dalamnya bisa mengakses anggota private kelas lain tanpa harus membuat variabel atau metode anggotanya menjadi public. akan tetapi kelas Garis akan disimpan dalam file terpisah.

Misalnya suatu kelas yang melambangkan permainan kartu.NamaKelasBertingkat. Struktur MainKartu bisa berbentuk seperti : class MainKartu { // Melambangkan permainan kartu class Pemain { // Melambangkan salah satu pemain game ini . jika tidak maka harus dibuat statik. Mari lihat contoh berikut. objek "this" akan secara otomatis digunakan). dan memiliki akses penuh atas anggota kelas induknya. Dari luar kelas induknya. Objek dari kelas bertingkat tersebut dihubungkan secara permanen dengan objek dari kelas induknya. Dengan kata lain. setiap objek yang diciptakan dari kelas induknya memiliki kopi kelas bertingkat masing-masing. . kita harus membuat objek yang merupakan kelas induknya. dan mungkin bisa memberi pemahaman lebih baik bagaimana kelas bertingkat non-statik sebetulnya merupakan hal yang sangat alami. // Tumpukan kartu . sehingga bisa diakses dengan nama yang sederhana.Anggota non-statik suatu kelas menjelaskan apa yang akan disimpan dalam objek yang diciptakan dari kelas tersebut. . . misalnya namaVariabel adalah variabel yang merujuk pada objek yang memiliki kelas bertingkat tersebut. Pada dasarnya. Sebetulnya cara ini agak langka. Dua objek kelas bagian dalam pada dua objek induk merupakan objek berbeda karena metode dan variabel instansi yang bisa diakses berasal dari objek yang berbeda. (Ketika bekerja di dalam kelas. Kopi ini memiliki akses ke semua variabel dan metode instansi objek tersebut. . Kelas ini memiliki kelas beringkat yang melambangkan para pemainnya. maka kelas tersebut harus dibuat non-statik. kelas bertingkat non-statik harus dipanggil dalam bentuk namaVariabel. } // akhir kelas Pemain private Tumpukan tumpukan. Hal ini juga berlaku (secara logis) dari kelas bertingkat non-statik. Kelas bertingkat non-statik biasanya digunakan hanya di dalam kelas induknya. aturan untuk menentukan kapan suatu kelas bisa dimasukkan ke dalam kelas lain sebagai kelas statik atau non-statik adalah : Jika kelas tersebut perlu menggunakan variabel atau metode instansi suatu objek (bukan variabel atau metode statik kelas). UNtuk membuat objek yang merupakan kelas bertingkat non-statik.

Dalam metode instansi objek [code]MainKartu. tapi ini jarang dilakukan). Kelas anonim dapat dibuat dengan menggunakan variasi dari operator new dengan bentuk new kelassuper_atau_interface () { metode_dan_variabel } Konstruktor ini membuat suatu kelas baru tanpa memberi nama. Pemain kartu pada game tersebut akan menggunakan tumpukan kartunya sendiri sedangkan pemain kartu pada game yang lain akan menggunakan tumpukan kartu lain lagi.Pemain()". Jika Pemain merupakan kelas bertingkat statik. objek Pemain bisa dibuat dengan perintah "new Pemain()". maka pemain tersebut akan bermain di semua permainan kartu. seperti halnya kelas biasa. Apakah berguna membuat kelas bertingkat jika begini kondisinya? Mungkin ya mungkin tidak. maka game memiliki kelas Pemain[code] sendiri. Bentuk operator [code] seperti ini bisa digunakan dalam pernyataan apapun di mana pernyataan new biasa digunakan.. mungkin kita harus menulis kelas bertingkat dan kemudian menggunakan kelas tersebut hanya 1 kali dalam program kita. Kita juga bisa membuat kelas anonim yang diturunkan dari interface. (Objek Pemain bisa dibuat di luar kelas MainKartu dengan perintah seperti "new game. Dalam kasus seperti ini kita juga bisa membuat kelas bertingkat anonim. Dalam beberapa kasus. yang tentu saja tidak mungkin terjadi. Masing-masing objek MainKartu memiliki tumpukan dan Pemain sendiri-sendiri. } // akhir kelas MainKartu Jika game adalah variabel dengan tipe MainKartu. Objek Pemain memiliki akses ke variabel instansi tumpukan dalam objek MainKartu. Misalnya kita ingin membuat objek berupa gambar bujur sangkar berisi warna merah dengan ukuran 100 x 100 piksel. Dalam hal ini. Kelas anonim sering digunakan untuk menangani event pada GUI (graphical user interfaces). . kelas anonim tersebut harus mengimplementasikan semua metode yang dideklarasikan oleh interface tersebut. Maksud dari pernyataan di atas adalah untuk membuat : "objek baru di dalam suatu kelas yang namanya sama dengan kelassuper_atau_interface dengan ditambah dengan metode_dan_varaibel baru. dan pada saat yang sama membuat objek dari kelas tersebut." Artinya pernyataan di atas sama dengan membuat objek baru dengan konfigurasi yang baru pula. Misalnya interface Gambar seperti didefinisikan di awal bagian ini.

red). Sifat Akses dalam Kelas Suatu kelas dapat dideklarasikan sebagai public.setColor(Color.100. Bagian ini membahas tentang paket.class dan seterusnya. g. KelasUtama$3.fillRect(10. Paket adalah salah satu jenis dari kotak hitam.) di akhir pernyataan ini bukan bagian dari definisi suatu kelas. dan kelas public dalam paket tersebut adalah antar muka dengan dunia luarnya. Variabel atau metode anggota ini juga bisa dideklarasikan sebagai private yang artinya hanya bisa diakses dari dalam kelas di mana dia dideklarasikan. KelasUtama$2. Bagian lain. kita bisa menggunakan kelas anonim untuk membuat objek sekaligus dalam satu pernyataan : Gambar kotakMerah = new Gambar() { void gambar(Graphics g) { g.100). Membuat variabel menjadi private memastikan bahwa tidak ada bagian lain yang akan bisa mengubah variabel ini kecuali dari dalam kelas atau objek itu sendiri. Ketika kelas Java dikompilasi. Tanda titik koma (. tidak boleh dibuat menjadi public. } }. tapi merupakan bagian dari pernyataan secara keseluruhan.class.class. misalnya. setiap kelas bertingkat anonim akan dibuat dalam file kelas terpisah. yang bisa diakses dari manapun. yang merupakan bagian internal dari bagaimana paket tersebut bekerja dan tidak boleh disentuh dari luar. maka nama file kelas untuk setiap kelas bertingkat anonimnya menjadi KelasUtama$1. Kelas pada applet misalnya harus juga dideklarasikan sebagai public supaya bisa diakses oleh web browser. Jika nama kelas utama adalah KelasUtama. Variabel atau metode anggota suatu kelas juga bisa dideklarasikan sebagai public yang juga berarti bisa diakses dari manapun. .Daripada membuat kelas baru kemudian menggunakan kelas tersebut untuk membuat objek. sehingga sistem operasi bisa menjalankan prosedur main() nya. Beberapa dari kelas ini memang sengaja dibuat public agar bisa diakses dari desktop atau program lain misalnya. Beberapa kelas harus dideklarasikan sebagai publik. Jika suatu kelas tidak dideklarasikan sebagai public maka ia hanya akan bisa diakses dari paket yang sama. misalnya sebagai aplikasi desktop biasa. Kelas yang tidak ditulis dalam suatu paket tertentu akan dimasukkan dalam paket default.10. Suatu paket seharusnya terdiri dari beberapa kelas yang saling berhubungan.

Dalam hal anggota statik dan non-statik digabung dalam satu kelas. di mana setiap objek yang diciptakan memiliki metode instansi masing-masing. Anggota protected digunakan untuk menambah fondasi bagi kelas turunannya. Menggabungkan Statik dan Non-Statik Seperti disebutkan sebelumnya. Ada satu jenis sifat akses lain yang bisa digunakan pada variabel atau metode anggota kelas. Dengan demikian.Jika kita tidak memberikan sifat akses pada metode atau variabel anggota tertentu. akan tetapi tetap tak terlihat dari dunia luar. Misalnya. metode instansinya menggunakan variabel statik atau memanggil subrutin statik. kelas dapat memiliki dua kegunaan yang sangat berbeda.Random telah diimpor sebelum kelas ini dibuat) public int dadu1. Metode instansi dimiliki oleh suatu objek. karena fungsinya hanya digunakan untuk menghasilkan nilai acak saja. suatu kelas dapat melakukan salah satu atau kedua fungsi tersebut secara bersamaan. Akan tetapi akan hanya ada satu variabel statik yaitu yang dimiliki oleh suatu kelas. Sifat protected digunakan apabila kita ingin variabel atau metode anggota tersebut bisa diakses oleh turunan kelas tersebut. kelas tersebut mengharapkan adanya interaksi antara bagian statik dan bagian non-statik dari suatu kelas. biasanya memiliki anggota protected. Atau juga bisa digunakan sebagai produsen pembuat objek. Misalnya anggap kita akan menulis kelas PasanganDadu yang menggunakan kelas Random seperti pada bagian sebelumnya untuk mengocok dadu.util. // Angka pada dadu pertama . Misalnya pada kode berikut ini : class PasanganDadu { private static Random randGen = new Random(). Kelas bisa digunakan untuk menggabungkan variabel dan subrutin statik. Objek PasanganDadu perlu mengakses objek Random. maka ia akan otomatis bisa diakses oleh semua kelas dalam paket yang sama. kita memiliki banyak objek yang bisa mengakses variabel statik tersebut bersama-sama. bukan oleh kelas tersebut. yaitu protected. Variabel dan subrutin non-statik dalam suatu kelas akan menentukan metode dan variabel instansi pada objek yang diciptakan dari kelas tersebut. Kelas yang didesain untuk diturunkan. // (Catatan: java. Dalam banyak kasus. Artinya lebih leluasa dari private tapi lebih ketat daripada public. Solusi yang bagus adalah dengan menggunakan variabel static yang digunakan oleh semua objek yang dibuat dari kelas PasanganDadu. Akan tetapi membuat objek Random untuk setiap objek PasanganDadu adalah terlalu berlebihan. Karena kita bisa membuat banyak objek dari suatu kelas.

dadu2= randGen. // Nilai ujian . } } // akhir kelas PasanganDadu Contoh lain adalah kelas Murid yang digunakan pada bagian sebelumnya. // Angka pada dadu kedua public PasanganDadu() { // Konstruktor. Membuat pasangan dadu dengan angka // awal berupa bilangan acak kocok(). Ketika objek baru dibuat.nextInt(6) + 1. public class Murid { private String nama.nextInt(6) + 1. // nomor murid unik public double ujian1. Untuk itu kita perlu melacak nomor baru yang belum dipakai dengan variabel nomorBerikutnya yang berbentuk variabel statik sehingga semua objek akan mengacu pada variabel yang sama. } public void kocok() { // Kocok dadu dengan membuat masing-masing dadu // bernilai bilangan acak 1 hingga 6 dadu1= randGen. // Nama murid private int nomorMurid. ujian2. ujian3. Kita tambahkan variabel instansi nomorMurid yaitu nomor unik yang berbeda untuk setiap murid. objek baru akan mengambil nilai nomorBerikutnya untuk dijadikan nomorMurid yang baru.public int dadu2.

} public double hitungRataRata() { // Hitung rata-rata nilai ujian return (ujian1 + ujian2 + ujian3) / 3. // simpan nomor murid berikutnya Murid(String namaBaru) { // Konstruktor objek Murid: // memberi nama. } public String getNama() { // Fungsi untuk mengambil isi variabel instansi private: nama return nama. nomorBerikutnya++. dan memberi nomor murid baru nama = namaBaru. nomorMurid = nomorBerikutnya. } public int getNomorMurid() { // Fungsi untuk membaca isi nomorMurid return nomorMurid. } .private static int nomorBerikutnya = 0.

} // akhir kelas Murid Inisialisasi "nomorBerikutnya = 0" hanya dilakukan satu kali, yaitu ketika kelas ini pertama kali dipanggil (pada saat program dijalankan). Ketika objek baru bertipe Murid dibuat, dan di dalam konstruktor perintah "nomorBerikutnya++;", maka nomor berikutnya akan disimpan untuk digunakan pada objek baru lainnya. Ketika objek pertama dibuat, nilai nomorBerikutnya akan bernilai 1. Ketika objek kedua dibuat, nilai nomorBerikutnya bernilai 2, dan seterusnya. Konstruktor akan menyimpan nilai baru nomorBerikutnya pada variabel instansinya sendiri yang tidak di-share dengan objek-objek lain yaitu nomorMurid. Dengan cara ini setiap murid baru akan selalu memiliki nomorMurid baru yang berbeda satu dengan yang lain.

Bab VII - Kebenaran dan Ketangguhan Program
Kita sering sekali menemukan program komputer yang gagal. Kesalahan sedikit dapat membuat program berperilaku tidak sesuai dengan yang diharapkan atau bahkan mati total. Kita sendiri sering mengalaminya. Dan kita sering mendengar berita atau cerita tentang kesalahan suatu software yang menyebabkan pesawat jatuh, sambungan telepon putus seketika, atau bahkan (dalam kasus yang langka) menyebabkan kematian orang. Program sebetulnya tidak sejelek yang kita pikir. Mungkin kita tidak bisa membuat program yang sama sekali bebas dari masalah, akan tetapi pemrograman yang baik dan alat pemrograman yang didesain dengan baik akan membantu kita membuat program dengan masalah yang sesedikit mungkin. Bagian ini akan membahas tentang program yang "benar" dan "tangguh". Kita juga akan melihat pengecualian (exceptions), yaitu salah satu alat dalam bahasa Java yang dapat membantu kita membuat program yang "tangguh" tersebut.
• • • •

Pengenalan tentang Program yang Benar dan Tangguh Membuat Program yang Benar Pengecualian dan Pernyataan "try ... catch" Pemrograman dengan Pengecualian

Pengenalan tentang Program yang Benar dan Tangguh
Suatu program disebut "benar" jika ia menyelesaikan suatu tugas sesuai dengan desainnya. Program disebut "tangguh" jika ia bisa menangani suatu situasi yang tidak biasa dengan cara yang masuk akal. Misalnya, suatu program didesain untuk membaca angka yang diketik oleh user, kemudian menampilkan angka dengan urutan tertentu. Program tersebut benar jika ia bekerja untuk angka berapa pun. Program tersebut tangguh jika program tersebut bisa menangani input yang salah, misalnya jika user memasukkan sesuatu yang bukan angka, misalnya, dengan cara memberi tahu user bahwa input yang dia masukkan salah, dan mengabaikan input yang

salah tersebut. Program yang tidak tangguh akan keluar tiba-tiba atau memberikan keluaran yang tidak bermakna dalam kondisi tertentu. Semua program harusnya bekerja dengan benar. (Program yang dibuat untuk mengurutkan angka tetapi tidak mengurutkan dengan benar adalah program yang tidak berguna). Program tidak selalu harus tangguh secara total. Akan tetapi tergantung pada siapa yang akan menggunakan dan bagaimana program tersebut digunakan. Misalnya, program kecil yang digunakan hanya oleh Anda sendiri tidak harus tangguh total, karena kita tahu batas-batas dan bagaimana program tersebut bekerja. Kebenaran suatu program sebenarnya lebih sulit dari apa yang kita bayangkan. Seorang programmer mencoba membuat program sesuai dengan spesifikasi tentang bagaimana sebuat program "seharusnya" bekerja. Hasil kerja programmer tersebut benar jika program yang ia buat bekerja sesuai dengan spesifikasinya. Tapi apakah itu berarti program tersebut benar? Bagaimana jika ternyata spesifikasinya kurang lengkap atau salah? Program yang benar seharusnya merupakan implementasi dari spesifikasi yang lengkap dan benar. Pertanyaannya apakah spesifikasi tersebut lengkap dan sesuai dengan yang diinginkan tercakup di luar domain ilmu komputer. Banyak pengguna komputer memiliki pengalaman di mana program tidak bekerja atau crash. Dalam banyak hal, masalah tersebut hanya mengganggu saja, tapi kadang-kadang masalahnya lebih kompleks dari itu, misalnya hilangnya data atau uang. Jika komputer diberi tugas penting, konsekuensinya akan lebih serius apabila program tersebut berperilaku tidak normal. Beberapa tahun yang lalu, kegagalan dua misi ruang angkasa ke Mars masuk dalam berita. Kedua kegagalan tersebut dipercaya karena masalah pada software, akan tetapi pada kedua kasus tersebut masalahnya bukan pada program yang tidak benar. Pada bulan September 1999, Orbiter Iklim Mars terbakar di atmosfer Mars karena data yang ditulis dalam satuan Inggris (inci, kaki, dll) dimasukkan ke dalam program komputer yang didesain untuk menerima input satuan Metrik (sentimeter, kilometer, dll). Beberapa bulan kemudian, Pendarat Kutub Mars jatuh karena softwarenya mematikan mesinnya terlalu cepat. Program yang dibuat seharusnya bisa mendeteksi tumpuan ketika pesawat mendarat dan baru kemudian mematikan mesin. Akan tetapi, roda pendarat kemungkinan macet yang menyebabkan program pemati mesin aktif sebelum pesawat menyentuh tanah. Sistem yang lebih tangguh akan mengecek terlebih dahulu ketinggian pesawat sebelum mesin dimatikan. Masih banyak beberapa kisah tentang masalah yang disebabkan oleh jeleknya desain atau implementasi suatu software. Silakan lihat buku Computer Ethics karangan Tom Forester dan Perry Morrison untuk melihat beberapa insiden yang pernah terjadi. (Buku ini menceritakan tentang isu etika dalam bidang komputer. Buku ini mungkin penting sekali untuk dibaca oleh orang yang berkecimpung dalam dunia ilmu komputer). Pada tahun 1985 dan 1986, satu orang tewas dan beberapa lainnya terluka karena overdosis radiasi, pada saat melakukan perawatan radiasi dengan mesin radiasi yang komputernya tidak diprogram dengan benar. DI kasus lain, selama 10 tahun hingga tahun 1992, sekitar 1000 pasien kanker menerima dosis radiasi sekitar 30% lebih rendah dari yang diberikan dokter karena kesalahan pemrograman. Pada tahun 1985, sebuah komputer di Bank of New York menghancurkan data-data transaksi sekuritas yang sedang berjalan karena adanya kesalahan pada program. Butuh kurang dari 24 jam untuk memperbaiki program tersebut, akan tetapi pada saat itu, bank sudah kehilangan sekitar 5 juta US dollar karena bunga overnight yang harus dipinjam untuk mengkover masalah tersebut.

Pemrograman sistem kendali inersia dari pesawat tempur F-16 bisa membalik pesawat dari atas ke bawah ketika digunakan di atas khatulistiwa, untungnya masalah ini sudah ditemukan dalam simulasi. Pemindai luar angkasa Mariner 18 hilang karena kesalahan di satu baris program. Kapsul luar angkasa Gemini V salah mendarat beberapa ratus kilometer lebih jauh karena programmer lupa untuk memasukkan perputaran bumi ke dalam perhitungan. Pada tahun 1990, layanan telephon jarak jauh AT&T terganggu di seluruh Amerika Serikat ketika program komputer yang baru dijalankan terbukti memiliki bug. Contoh-contoh di atas adalah beberapa yang pernah terjadi. Masalah software adalah masalah yang sangat umum. Sebagai programmer, kita harus mengerti kenapa itu bisa terjadi dan bagaimana cara mengatasinya. Salah satu bagian dari masalahnya dapat dilacak kepada bahasa pemrogramannya itu sendiri, begitu kata para penemu Java. Java didesain untuk memberikan proteksi terhadap beberapa jenis kesalahan. Bagaimana caranya suatu bahasa pemrograman menghindari kesalahan? Mari kita lihat beberapa contohnya. Bahasa pemrograman terdahulu tidak membutuhkan variabel untuk dideklarasikan. Pada bahasa pemrograman tersebut, ketika suatu nama variabel digunakan dalam program, variabel akan otomatis dibuat. Mungkin ini terlihat lebih mudah dan nyaman daripada harus mendeklarasikan variabel beserta tipenya terlebih dahulu. Akan tetapi, ada konsekuensinya : Kesalahan ketik sedikit saja akan membuat komputer menciptakan variabel baru yang sebetulnya tidak kita inginkan. Kesalahan seperti ini pernah terjadi dan mengakibatkan hilangnya pesawat ruang angkasa. Dalam bahasa pemrograman FORTRAN, perintah "DO 20 I = 1,5" adalah pernyataan pertama dari suatu perulangan. Sekarang, spasi tidak lagi suatu hal yang penting pada bahasa FORTRAN, sehingga perintah ini akan sama dengan "DO20I=1,5". Di lain pihak, perintah "DO20I=1.5" dengan tanda titik bukan koma, merupakan pernyataan pemberi nilai yang memberi nilai 1.5 ke dalam variabel DO20I. Misalnya ada kesalahan dalam mengetik koma menjadi titik, bisa jadi akan menyebabkan suatu roket meledak sebelum diluncurkan. Karena FORTRAN tidak memerlukan variabel untuk dideklarasi, kompilernya akan senang menerima perintah "DO20I=1.5". Ia akan membuat variabel baru bernama DO20I. Jika FORTRAN membutuhkan variabel untuk dideklarasikan di awal, kompiler akan mengeluarkan pesan kesalahan di awal karena variabel DO20I tidak pernah dideklarasikan sebelumnya. Hampir semua bahasa pemrograman saat ini perlu mendeklarasikan variabel sebelum digunakan, akan tetapi masih ada beberapa fitur pada bahasa pemrograman yang bisa menyebabkan kesalahan. Java sudah membuang fitur ini. Beberapa orang tidak suka karena ini membuat Java menjadi kurang feksibel dan kurang ampuh. Walaupun mungkin kritik ini benar, meningkatnya tingkat keamanan dan ketangguhan suatu program mungkin lebih dipentingkan dalam beberapa hal. Pertahanan yang paling baik untuk mencegah beberapa macam jenis kesalahan adalah mendesain bahasa pemrograman di mana membuat kesalahan tidak mungkin sama sekali. Dalam kasus lain, di mana kesalahan tidak bisa dihilangkan sama sekali, bahasa pemrograman bisa didesain sehingga apabila kesalahan terjadi, maka kesalahan ini akan dapat dideteksi secara otomatis. Paling tidak cara ini akan mencegah kesalahan tersebut membuat bencana yang lebih besar, karena akan memberi peringatan kepada programmer bahwa ada sesuatu bug yang harus diperbaiki. Mari lihat beberapa contoh yang diberikan Java untuk mengatasi permasalahan ini.

Suatu array dibuat dengan beberapa lokasi, dimulai dengan 0 hingga ke indeks maksimumnya. Kita tidak dibolehkan untuk menggunakan lokasi array di luar rentang yang sudah dibuat. Pada Java, jika kita memaksakan untuk melakukan itu, sistem akan otomatis mendeteksi hal ini. Pada bahasa pemrograman lain seperti C dan C++, programmer diberi keleluasaan penuh untuk memastikan bahwa indeks array berada di dalam rentang tersebut. Misalnya suatu array, A, memiliki tiga lokasi A[0], A[1], dan A[2]. Maka A[3], A[4], dan berikutnya adalah lokasi pada memori di luar array tersebut. Pada Java, apabila kita mencoba untuk menyimpan data pada A[3], Java akan mendeteksi ini. Program akan dihentikan saat itu juga (kecuali kesalahan ini "ditangkap" yang akan dibahas kemudian). Pada bahasa C atau C++, komputer akan diam saja dan melakukan penyimpanan di lokasi ini. Hasilnya akan tidak bisa diprediksi. Konsekuensinya akan jauh lebih berat daripada jika program berhenti (Kita akan diskusikan tentang tumpahan buffer di bagian ini nanti). Pointer (penunjuk memori) juga merupakan kesalahan pemrograman yang paling sulit. Dalam Java, variabel dari suatu objek menyimpan pointer atau rujuan ke alamat memori di mana objek tersebut disimpan, atau isinya bisa juga null. Jika kita mencoba untuk menggunakan nilai null seperti layaknya rujukan ke objek sungguhan, maka sistem komputer akan mendeteksinya. Dalam bahasa pemrograman lain, lagi-lagi, adalah tanggung jawab programmer untuk mencegah digunakannya rujukan ke null. Pada komputer Macintosh lama, alamat null merupakan alamat ke lokasi di memori dengan alamat 0. Program dapat menggunakan memori di dekat alamat 0. Sayangnya, Macintosh menyimpan data penting tentang sistem di lokasi tersebut. Mengubah data di lokasi tersebut akan membuat sistem crash atau hang, bukan hanya program tersebut saja tetapi keseluruhan sistem operasi akan berhenti. Kesalahan pointer lain adalah jika isi pointer menunjuk pada tipe data yang salah atau lokasi di memori yang tidak memiliki objek sama sekali. Kesalahan seperti ini tidak mungkin dalam bahasa Java, karena programmer tidak diperbolehkan untuk mengganti pointer sama sekali. Di dalam bahasa pemrograman lain, programmer bisa mengganti lokasi pointer ke lokasi lain, intinya, ke lokasi memori manapun. Jika tidak dilakukan dengan benar, pointer ini bisa menunjuk pada lokasi berbahaya atau menghasilkan sesuatu yang tidak bisa diperkirakan. Kesalahan lain yang bisa terjadi pada Java adalah kebocoran memori. Pada Java, sewaktu tidak ada lagi pointer yang merujuk ke pada suatu objek, objek tersebut akan diambil oleh pemulung memori, sehingga memori tersebut dapat digunakan lagi oleh bagian program lain. Dalam bahasa pemrograman lain, programmer bertanggung jawab untuk mengembalikan memori yang tidak digunakan kepada sistem operasi. Jika programmer tidak melakukannya, makan memori yang tidak terpakai akan terakumulasi, sehingga jumlah memori yang tersedia akan berkurang. Ini adalah salah satu contoh masalah umum yang terjadi pada komputer Windows di mana banyak sekali kebocoran memori yang terjadi, sehingga komputer harus direstart ulang setiap beberapa hari. Banyak program yang terjangkit masalah tumpahan buffer (buffer overflow error). Tumpahan buffer sering menjadi berita utama karena hal ini sering mengakibatkan kompromi masalah keamanan komputer. Ketika komputer menerima data dari komputer lain dari network atau internet misalnya, data tersebut akan disimpan dalam buffer. Buffer adalah bagian memori yang telah dialokasikan program untuk menyimpan data tersebut. Tumpahan buffer terjadi jika data yang diterima lebih banyak dari jumlah data yang bisa ditampung oleh buffer. Pertanyaannya adalah kapan ini terjadi? Jika kesalahan ini bisa dideteksi oleh program atau program yang mengatur lalu lintas network, maka satu-satunya kemungkinan adalah pada karena kesalahan transmisi data pada network.

Masalah utamanya terjadi ketika program tidak bisa mendeteksi tumpahan buffer secara benar. Dalam hal ini, software terus mensuplai data ke memori meskipun buffer telah terisi penuh, dan data lebihnya disimpan pada bagian memori yang tidak dialokasikan untuk buffer tersebut. Bagian memori yang tertunpah tersebut mungkin digunakan untuk fungsi lain. Mungkin juga digunakan untuk menyimpan data penting lain. Atau bahkan mungkin menyimpan kode program itu sendiri. Ini yang akan menjadi masalah keamanaan. MIsalnya tumpahan buffer ini menimpa bagian dari program. Ketika komputer mengeksekusi bagian program yang telah diganti, maka sebetulnya komputer akan menjalankan data yang diterima dari komputer lain. Data ini bisa berisi apa saja. Bisa jadi program untuk menghentikan komputer atau bahkan mengendalikan komputer. Programmer jahat yang bisa menemukan kesalahan tumpahan memori dalam software pengendali network bisa menggunakan lubang ini untuk menjalankan program-program jahatnya. Untuk software yang ditulis dalam Java, kesalahan tumpahan buffer tidak dimungkinkan. Bahasa Java tidak mungkin menyimpan data di memori yang tidak dialokasikan kepadanya. Untuk bisa menyimpan data, komputer membutuhkan pointer yang menunjuk pada lokasi memori yang belum terpakai, atau menggunakan lokasi array yang berada di luar lokasi yang disediakan untuk array tersebut. Seperti dijelaskan sebelumnya, kedua kemungkinan tersebut tidak diperbolehkan sama sekali pada Java. (Akan tetapi, masih mungkin kesalahan seperti ini muncul pada kelas standar Java, karena beberapa metode pada kelas ini sebenarnya ditulis dalam bahasa C bukan Java). Sudah jelas desain bahasa bisa membantu mencegah kesalahan atau membantu mendeteksi masalah yang mungkin terjadi. Atau dibutuhkan pengujian, misalnya menguji apakah pointer bernilai null. Beberapa programmer mungkin merasa harus mengorbankan kecanggihan dan efisiensi. Akan tetapi, ada banyak situasi di mana keamanan merupakan prioritas utama. Java didesain untuk situasi seperti ini. Ada satu bagian di mana desainer Java tidak memasukkan pendeteksi masalah secara otomatis, yaitu perhitungan numerik. Pada Java, nilai suatu bilangan int dinyatakan dalam bilangan biner 32-bit. Dengan 32 bit, maka terdapat kurang lebih 4 milyar bilangan yang bisa dibentuk. Nilai int memiliki rentang antara -2147483648 hingga 2147483647. Apa yang terjadi jika hasil perhitungan berada di luar rentang ini? Misalnya, berapa 2147483647 + 1? Dan berapa 2000000000 * 2? Jawaban yang benar secara matematis berada di luar nilai int. Contoh-contoh di atas disebut tumpahan bilangan bulat (integer overflow). Dalam banyak kasus, tumpahan bilangan bulat termasuk suatu kesalahan. Akan tetapi Java tidak otomatis mendeteksi kesalahan tersebut. Misalnya, perhitungan 2147483647 + 1 akan bernilai negatif -2147483648 (Apa yang terjadi sebenarnya adalah bit tambahan di luar bit ke-32 diabaikan. Nilai yang lebih besar dari 2147483647 akan "terpotong" sehingga menjadi nilai negatif. Secara matematis, hasilnya akan selalu merupakan sisa pembagian dari pembagian dengan 232). Banyak kesalahan program yang disebabkan oleh kesalahan semacam ini. Program tersebut benar, akan tetapi tidak bisa menangani bilangan lebih besar daripada 32 bit. Contoh sederhana adalah kesalahan Y2K sebenarnya merupakan kesalahan yang mirip dengan ini. Untuk jenis bilangan real seperti double, masalahnya bahkan lebih kompleks lagi. Bukan hanya tumpahan yang mungkin terjadi. Untuk jenis double, rentangnya berlaku hingga 10308. Nilai yang lebih dari nilai ini tidak "terpotong" menjadi negatif. Akan tetapi ia akan diubah menjadi suatu konstanta yang bernilai tak berhingga. Nilai Double.POSITIVE_INFINITY dan Double.NEGATIVE_INFINITY melambangkan nilai positif tak hingga dan negatif tak hingga.

Nilai spesial lainnya dari tipe data double adalah Doube.NaN atau bukan bilangan (not a number), yang melambangkan suatu nilai yang tidak berarti. Misalnya pembagian dengan 0 atau akar kuadrat suatu bilangan negatif. Kita bisa menguji apakah suatu variabel berisi bukan bilangan dengan memanggil fungsi yang bertipe keluaran boolean, yaitu Double.isNaN(x). Untuk bilangan real, ada komplikasi tambahan yaitu hampir semua bilangan real hanya bisa dilambangkan dalam bentuk pendekatan. Bilangan real bisa memiliki jumlah digit di belakang koma yang tak terhingga banyaknya. Nilai bertipe double biasanya akurat sekitar 15 digit di belakang koma. Bilangan real 1/3, misalnya, berarti 0.33333333......, dan bilangan ini tidak bisa digantikan dengan bilangan dengan jumlah bit terbatas. Perhitungan dengan bilangan real biasanya memiliki kesalahan akurasi. Sebenarnya, jika kita kurang berhati-hati, akan menyebabkan perhitungan sama sekali salah. Ada bidang tertentu dalam ilmu komputer yang dinamakan analisis numerik yang berkonsentrasi pada algoritma untuk memanipulasi bilangan real. Tidak semua kesalahan yang mungkin terjadi bisa dideteksi otomatis oleh Java. Lebih jauh, bahkan ketika suatu kesalahan bisa dideteksi secara otomatis, reaksi standar dari sistem adalah melaporkan kesalahan dan menghentikan jalannya program. Ini bukan ciri program yang tangguh! Sehingga programmer harus mempelajari teknik untuk mencegah dan mengatasi kesalahan. Topik ini akan dibahas pada bab ini.

Membuat Program yang Benar
Program benar tidak jadi dengan sendirinya. Ia membutuhkan perencanaan dan perhatian kepada detail untuk mencegah kesalahan dalam program. Ada beberapa teknik yang bisa digunakan oleh programmer untuk meningkatkan kebenaran suatu program. Dalam beberapa kasus, kita bisa membuktikan bahwa program tersebut benar. Yaitu dengan menggunakan pembuktian secara matematis bahwa urutan penghitungan yang dilakukan program akan selalu menghasilkan hasil yang benar. Pembuktian yang komprehensive sangat sulit dibuat karena secara praktek pembuktian semacam ini hanya bisa dilakukan pada program yang cukup kecil. Seperti telah disebutkan sebelumnya, program yang benar menurut spesifikasi tidak berguna apabila spesifikasinya salah. Artinya, bahkan dalam pemrograman sehari-hari pun, kita harus terus mencari ide dan teknik yang bisa kita gunakan untuk membuktikan bahwa program yang kita tulis adalah benar. Ide dasarnya adalah proses (process) dan keadaan (state). Suatu keadaan terdiri dari semua informasi yang terkait dengan eksekusi suatu program pada saat tertentu. Keadaan mencakup, misalnya, nilai semua variabel pada program, keluaran yang telah diproduksi, input yang sedang diambil, dan posisi dalam di mana program tersebut sedang dieksekusi. Proses adalah urutan keadaan yang harus dilalui oleh komputer ketika menjalankan suatu program. Dari sudut pandang ini, arti suatu pernyataan dalam suatu program dapat diekspresikan dalam akibat apa yang dihasilkan dari eksekusi suatu perintah terhadap keadaan saat itu. Sebagai contoh sederhana, arti dari pernyataan "x = 7;" adalah setelah pernyataan ini dieksekusi, nilai

dari variabel x adalah 7. Kita bisa yakin tentang fakta ini, sehingga fakta ini bisa dijadikan salah satu bukti matematis. Sebenarnya, kita juga seringkali bisa menilai suatu program dan menyimpulkan bahwa suatu fakta adalah benar pada saat tertentu pada eksekusi suatu program. Misalnya, perhatikan perulangan berikut : do { N = Math.random(); } while (N <= 0.5); Setelah perulangan selesai, kita yakin betul bahwa nilai variabel N pasti lebih besar dari 0.5. Perulangan tidak bisa berhenti jika kondisi ini tidak tercapai. Bukti ini merupakan bagian dari arti perulangan while. Lebih umum, jika perulangan while menggunakan pengujian "while (kondisi)" maka bisa dipastikan bahwa setelah perulangan selesai kondisi bernilai false. Kemudian kita bisa menggunakan fakta ini untuk menyimpulkan apa yang akan terjadi ketika eksekusi program berlanjut. (Dengan perulangan, kita juga harus memastikan kapan perulangan tersebut akan berakhir. Hal ini harus dipikirkan lebih lanjut secara terpisah). Suatu fakta yang pasti benar setelah bagian program dieksekusi disebut kondisi akhir dari bagian program tersebut. Kondisi akhir adalah fakta yang bisa kita gunakan untuk menyimpulkan tentang perilaku suatu program. Kondisi akhir suatu program secara keseluruan adalah fakta yang bisa dibuktikan ketika program selesai dieksekusi. Suatu program bisa dibuktikan bahwa ia melakukan fungsinya dengan benar jika kondisi akhirnya sesuai dengan spesifikasi program. Misalnya, kita lihat potongan program berikut, di mana semua variabelnya memiliki tipe double: det = B*B - 4*A*C; x = (-B + Math.sqrt(det)) / (2*A); Persamaan kuadrat (darti matematika di SMU) menyatakan bahwa nilai x adalah solusi persamaan A*x2 + B*x + C = 0 jika det bernilai 0 atau lebih. Jika kita menganggap atau menjamin bahwa B*B - 4*A*C >= 0 dan A != 0, maka x yaitu solusi persamaan kuadrat merupakan kondisi akhir. Kita sebut B*B - 4*A*C >= 0 sebagai kondisi awal potongan program tersebut. Kondisi A != 0 adalah kondisi awal lainnya. Kondisi awal adalah kondisi yang harus bernilai benar pada suatu waktu di tengah eksekusi program untuk menjamin bahwa program akan dapat terus dieksekusi tanpa kesalahan. Kondisi awal adalah sesuatu yang kita ingin selalu benar. Kondisi awal harus kita cek agar program kita benar. Mari kita lihat potongan program yang lebih panjang berikut ini. Program ini menggunakan kelas KonsolInput yang dibahas pada bagian sebelumnya.

println("Input Anda tidak benar."). kita yakin bahwa kondisi awal telah dipenuhi. Bagaimana pun kondisinya.out.print("B = ").out. akan tetapi programnya bukan implementasi sempurna dari algoritma ini.do { System. kita tahu bahwa salah satu kondisi awal tidak bisa dipenuhi.) Berikut ini adalah contoh lain. Potongan progam ini menghitung solusi suatu persamaan dengan benar dan bisa dibuktikan secara matematis (Sebetulnya karena ada masalah utama dalam merepresentasi angka terutama bilangan real pada komputer.").print("C = ").out.out. dan C. x = (-B + Math.out.sqrt(det)) / (2*A). Kondisi awal untuk dua baris terakhir sudah dipenuhi.ambilDouble(). System. System. } while (A == 0 || B*B . B. C = KonsolInput. B*B-4*A*C harus >= 0. masukkan lagi.4*A*C < 0) System. Di bagian awal pernyataan if.4*A*C < 0).4*A*C.print("A = "). di mana solusi dihitung kemudian dicetak ke layar. sehingga kondisi akhir bahwa x merupakan solusi persamaan A*x2 + B*x + C = 0 juga benar. hal ini tidak 100% benar. if (A == 0 || B*B . System. A = KonsolInput. B = KonsolInput. Di bagian lain.println("Masukkan A. di mana kondisi awal diuji dengan suatu perintah. program akan tetap benar. kita yakin bahwa B*B-4*A*C >= 0 dan juga A != 0. Setelah perulangan berakhir. .ambilDouble().ambilDouble(). Algoritma ini benar. det = B*B .

4*A*C.out.").out.out. if (A != 0 && B*B . kondisi awalnya adalah 0 <= i < A.println("Masukkan nilai A. Komputer akan menguji kondisi ini ketika ia mengevaluasi A[i]. C = KonsolInput.print("A = ").out. A = KonsolInput.ambilDouble(). program akan dihentikan.out. kita harus menguji bahwa indeks i berada di dalam nilai yang diperbolehkan (Sebetulnya .println("Nilai A tidak boleh 0.sqrt(disc)) / (2*A).println("Karena B*B .print("C = "). dan jika kondisi tidak dipenuhi. misalnya A[i]. Untuk A[i]. System. Misalnya. Untuk mencegah hal ini.println("persamaan A*X*X + B*X + C = 0 tidak memiliki solusi.System.out. } else { System.print("B = ")."). akan lebih baik jika kita mencari tahu kondisi awal suatu program dan memikirkan bagaimana program kita harus menanganinya. System.length. B = KonsolInput. kondisi awal suatu program bisa memberi informasi tentang bagaimana cara menulis program. Indeksnya harus berada di dalam rentang yang diperbolehkan pada array tersebut. dan C. x = (-B + Math.ambilDouble().4*A*C kurang dari nol. maka").out.4*A*C >= 0) { det = B*B .ambilDouble(). Sering kali.println("Solusi persamaan A*X*X + B*X + C = 0 is " + x). } else if (A == 0) { System. memiliki suatu kondisi awal. B. } Ketika kita menulis suatu program.").out. System. System. untuk setiap referensi pada array. System.

akan tetapi mari kita abaikan untuk sementara waktu. Pengecualian dan Pernyataan "try . yaitu : i = 0.. } if (i == A.length) System. maka perulangan akan berhenti ketika A[i] == x. catch" . while (i < A.) Misalnya kode berikut digunakan untuk mencari nilai x di dalam array A : i = 0. while (A[i] != x) { i++. kita bisa menambahkan pengujian untuk menjamin bahwa kondisi awal untuk merujuk pada A[i] bisa dipenuhi. } Dalam program ini.out.out.length atau A[i] == x. Pada saat tersebut. } Sekarang. maka nilai i akan terus dinaikkan hingga nilainya sama dengan A. Akan tetapi. else System. Pernyataan if bisa ditambahkan di akhir perulangan untuk menguji apa yang menyebabkan perulangan berhenti : i = 0. referensi ke A[i] menjadi ilegal sehingga program akan dihentikan. yaitu x harus ada di dalam array. Setelah selesai.println("x berada di luar array").length && A[i] != x) { i++. jika x tidak berada di dalam array. kita melihat bahwa program tersebut memiliki kondisi awal. while (i < A..length. perulangan pasti akan selesai. yaitu A tidak boleh null.length && A[i] != x) { i++.println("x berada pada posisi " + i). nilai i akan bernilai i == A.ada lagi kondisi awal yang lain. Untuk mencegah hal ini. JIka kondisi awal ini dipenuhi.

Membuat program untuk bekerja dalam kondisi ideal jauh lebih mudah daripada membuat program yang tangguh. Ketika ini terhadi. Salah satu pendekatanya adalah dengan melihat kemungkinan masalah yang mungkin terjadi dan menambahkan tes/pengujian pada program tersebut untuk setiap kemungkinan masalah yang mungkin terjadi. Tidak berarti bahwa interpreter juga akan crash. atau bisa juga kasus tertentu yang kita inginkan terpisah dari algoritma kita. interpreter akan menangkap pengecualian yang tidak ditangkap . dan program berada dalam bahaya akan crash.. program akan berhenti jika mencoba mengakses elemen array A[i]. kita sebut bahwa pengecualian tersebut di-lempar-kan (thrown). Atau dengan kata lain. Metode ini disebut sebagai penanganan pengecualian (exception-handling). Program tangguh harus dapat mengantisipasi kemungkinan adanya indeks yang tak masuk akal dan menjaganya dari kemungkinan itu. Pengecualian. Akan tetapi crash bisa dihindari jika pengecualian tersebut ditangkap (catch) dan ditangani dengan cara tertentu. // Proses elemen A[i] } Ada beberapa masalah yang mungkin terjadi dengan pendekatan seperti ini. di mana i tidak berada di dalam rentang yang dibolehkan.. mungkin saja thread lain akan terus berjalan apabila thread yang satu berhenti. (Lebih tepat apabila disebut thread yang melemparkan pengecualian tersebut akan berhenti. Kata "pengecualian" diartikan sesuatu yang lebih umum daripada "kesalahan". Dalam program multithreading. bisa berupa kesalahan. Adalah hal yang sangat sulit dan kadang kala tidak mungkin untuk mengantisipasi segala kemungkinan yang dapat terjadi. program yang crash berarti bahwa program tersebut berhenti berjalan secara prematur. Misalnya bisa dilakukan dengan : if (i < 0 || i >= A. Ketika pengecualian terjadi dalam eksekusi suatu program. Termasuk di antaranya adalah kondisi yang mungkin terjadi yang berada di luar aliran suatu program. Program tangguh dapat tahan dari kondisi yang tidak biasa atau dalam kondisi "pengecualian". Suatu pengecualian dapat dilempar oleh satu bagian program dan ditangkap oleh bagian program lain. Misalnya. Pengecualian yang tidak ditangkap secara umum akan menyebabkan program berhenti. Java (seperti C++) membutuhkan metode alternatif yang lebih rapi dan terstruktur untuk menghadapi masalah yang mungkin terjadi ketika program dijalankan. aliran program artinya terlempar dari jalurnya.length) { .) Karena program Java dijalankan di dalam interpreter. Untuk mengantisipasi semua masalah yang mungkin terjadi bisa jadi membuat program sederhana menjadi lautan pernyataan if. Kadang tidak selalu jelas apa yang harus dilakukan apabila suatu kesalahan ditemui... // Lakukan sesuatu untuk menangani indeks i diluar rentang } else { .

Dalam banyak kasus. jangan terlalu bernafsu untuk menangkap semua kesalahan hanya karena kita ingin program kita tidak crash. kelas turunan dari kelas Exception melambangkan pengecualian yang memang seharusnya ditangkap. Informasi ini selalu terdiri dari tumpukan panggilan subrutin (subrutin call stack). Jika kita tidak memiliki cara untuk menanganinya. program yang crash sering menghentikan seluruh sistem hingga kita menekan tombol reset. Kita sebaiknya tidak mencoba untuk menangkap dan menangani kesalahan jenis ini. Dalam banyak bahasa pemrograman lainnya. Jika kelas tersebut dipanggil ketika program sedang berjalan. Interpreter akan merespon dengan menghentikan jalannya program. Di lain pihak. Kedua kelas turunan ini pada akhirnya memiliki banyak kelas turunan lain. atau bisa juga memiliki data lain.) Biasanya. misalnya RuntimeException. kejadian seperti itu tidak mungkin -. Objek tersebut membawa informasi (dalam variabel instansinya) dari tempat di mana pengecualian terjadi ke titik di mana ia bisa ditangkap dan ditangani. pengecualian seperti ini adalah sesuatu yang mungkin biasa disebut "kesalahan". Kebanyakan turunan dari kelas Error merupakan kesalahan serius dalam mesin virtual Java yang memang seharusnya menyebabkan berhentinya program karena sudah tidak dapat diselamatkan lagi. Kelas ini mengelompokkkan pengecualian umum misalnya ArithmeticException yang terjadi misalnya ada pembagian dengan nol.yang artinya ketika hal itu terjadi.Throwable atau kelas turunannya. . Throwable memiliki dua kelas turunan langsung. (Akan tetapi. Ketika pengecualian terjadi. yaitu daftar di mana dan dari mana subrutin tersebut dipanggil dan kapan pengecualian tersebut dilemparkan. (Karena suatu subrutin bisa memanggil subrutin yang lain. bukan program kita. ArrayIndexOutOfBoundsException yang terjadi jika kita mencoba mengakses indeks array di luar rentang yang diijinkan. maka kita tidak bisa melanjutkan program tersebut sama sekali. Objek yang dilemparkan harus diciptakan dari kelas standar java. Kelas Exception memiliki kelas turunan lainnnya. yaitu Error dan Exception. akan tetapi kesalahan seperti ini adalah jenis yang bisa ditangani dengan cara yang baik.oleh program. maka yang salah adalah komputer kita. dan NullPointerException yang terjadi jika kita mencoba menggunakan referensi ke null di mana seharusnya referensi objek diperlukan. Misalnya ClassFormatError dilempar karena mesin virtual Java menemukan data ilegal dalam suatu file yang seharusnya berisi kelas Java yang sudah terkompilasi. Kita juga bisa membuat kelas pengecualian baru untuk melambangkan jenis pengecualian baru. beberapa subrutin bisa aktif dalam waktu yang sama.lang. Secara umum. setiap jenis pengecualian dikelompokkan dalam kelas turunan Throwable. yang terjadi adalah program tersebut melemparkan suatu objek. objek pengecualian juga memiliki pesan kesalahan mengapa ia dilemparkan. Dalam Java. mungkin menangkap pengecualian dan membiarkannya akan menyebabkan masalah lain di tempat lain).

Maksudnya memberi tahu komputer untuk "mencoba" (try) menjalankan suatu perintah. Untuk menangkap pengecualian pada program Java. Tapi jika pengecualian dilempar pada saat mencoba melaksanakan perintah tersebut. program yang melemparkan ArrayIndexOutOfBoundsException dan tidak menanganinya akan menghentikan program saat itu juga. Jika berhasil. Untuk pengecualian lain selain Error dan RuntimeException beserta kelas turunannya. Misalnya. pengecualian wajib ditangani. Diagram berikut menggambarkan hirarki suatu kelas turunan dari kelas Throwable. RuntimeException dan Error memiliki sifat yang sama yaitu program bisa mengabaikannya. Misalnya. . try { double determinan = M[0][0]*M[1][1] . kita menggunakan pernyataan try.RuntimeException biasanya menginidikasikan adanya bug dalam program yang harus diperbaiki oleh programmer.M[0][1]*M[1][0]. semuanya akan berjalan seperti biasa. ("Mengabaikan" artinya kita membiarkan program crash jika pengecualian tersebut terjadi). Kelas yang membutuhkan penanganan pengecualian wajib ditunjukkan dalam kotak merah. kita bisa menangkapnya dan menanganinya.

} catch ( ArrayIndexOutOfBoundsException e ) { System. Akan tetapi jika ada pengecualian ArrayIndexOutOfBoundsException. kecuali pengecualian ini ditangkap di tempat lain).").out. maka komputer akan langsung lompat ke dalam blok setelah pernyataan "catch (ArrayIndexOutOfBoundsException)". maka bagian "catch" akan diabaikan. seperti : try { double determinan = M[0][0]*M[1][1] .println("Determinan matriks M adalah " + determinan). sebenarnya yang dilemparkan adalah objek. pengecualian NullPointerException tidak ditangkap. Kita bisa menangkap pengecualian NullPointerException dengan menambah klausa catch lain.M[0][1]*M[1][0]. } catch ( ArrayIndexOutOfBoundsException e ) { System. Dalam pernyataan try di atas.System. System.out.out.out.println( e. } Contoh ini menunjukkan bagaimana caranya menggunakan beberapa klausa catch. kita mencegah program berhenti tiba-tiba. e adalah nama variabel (bisa kita ganti dengan nama apapun terserah kita).getMessage() ).println("Determinan M tidak bisa dihitung karena ukuran M salah."). Mungkin kita akan sadar bahwa ada kemungkinan kesalahan lagi dalam blok di dalam pernyataan try. Sebelum menjalankan klausa .out. Jika variabel M berisi null. } catch ( NullPointerException e ) { System. Dengan cara ini. Blok ini disebut blok yang menangani pengecualian (exception handler) untuk pengecualian ArrayIndexOutOfBoundsException".println("Determinan matriks M adalah " + determinan). maka pengecualian NullPointerException akan dilemparkan. System.println("Determinan M tidak bisa dihitung karena ukuran M salah. Ingat kembali bahwa ketika pengecualian terjadi. sehingga akan diproses seperti biasa (yaitu menghentikan program saat itu juga.out.print("Kesalahan program! M tidak ada: " + ). } Komputer mencoba menjalankan perintah di dalam blok setelah kata "try". Jika tidak ada pengecualian.

} Karena objek yang bertipe ArrayIndexOutOfBoundsException maupun NullPointerException juga bertipe RuntimeException. Kita bisa membuat klausa catch secara spesifik hingga tahu persis apa yang salah. ada kesalahan yang terjadi. dan mungkin kita akan bosan jika harus menulis try . misalnya : try { double determinan = M[0][0]*M[1][1] .println("Maaf. Oleh karena itu kita sebut penanganan ini tidak wajib.").catch.M[0][1]*M[1][0]. Sepertinya kita jarang harus menangani kesalahan indeks ataupun kesalahan pointer kosong seperti di atas.println("Determinan matriks M adalah " + determinan). Ia hanya memberikan alat yang mungkin kita gunakan dengan cara memberi tahu di mana kesalahan mungkin muncul).out. Masalahnya mungkin terlalu banyak. maka perintah seperti di atas akan menangkap kesalahan indeks maupun kesalahan pointer kosong dan juga pengecualian runtime yang lain.. Yang penting kita mengisi variabel tersebut dengan sesuatu yang bukan null dan menjaga agar program tidak keluar indeks sudah cukup. Objek ini mengandung informasi tentang pengecualian tersebut.out. Metode ini akan mencetak daftar subrutin yang dipanggil sebelum pengecualian ini dilempar. Akan ada banyak hal yang bisa jadi masalah. Bentuk pernyataan try sebenarnya lebih kompleks dari contoh di atas. komputer mengisi variabel ini dengan objek yang akan ditangkap. Ingat bahwa baik ArrayIndexOutOfBoundsException dan NullPointerException adalah kelas turunan dari RuntimeException.printStackTrace(). atau menggunakan klausa penangkap umum. e. Kita bisa menangkap semua pengecualian dalam kelas RuntimeException dengan klausa catch tunggal. pesan kesalahan yang menjelaskan tentang pengecualian ini bisa diambil dengan metode getMessage() seperti contoh di atas. } catch ( RuntimeException e ) { System. System. (Makanya penanganan pengecualian tidak menyebabkan program makin tangguh. Sintaksnya secara umum dapat ditulis seperti: try { . Informasi ini bisa menolong kita untuk melacak dari mana kesalahan terjadi. catch setiap kali kita menggunakan array. Ini menunjukkan mengapa kelas pengecualian disusun dalam bentuk hirarki kelas. Contoh di atas mungkin tidak begitu realistis.. Misalnya.

perintah } klausa_catch_tambahan klausa_finally_tambahan Ingat bahwa di sini blok ( yaitu { dan } ) diperlukan. Ada beberapa kejadian di mana suatu program memang harus melempar pengecualian. Misalnya apabila program tersebut menemukan adanya kesalahan pengurutan atau kesalahan lain. tidak peduli apakah ada pengecualian yang dilempar atau tidak. Biasanya merupakan kelas turunan dari kelas Exception. Program bisa melempar pengecualian dengan harapan di bagian lain pengecualian ini akan ditangkap dan diproses. objek_pengecualian harus merupakan objek yang bertipe kelas yang diturunkan dari Throwable. dan juga klausa finally boleh ada boleh tidak. tapi tidak ada cara yang tepat untuk menanganinya di tempat di mana kesalahan tersebut ditemukan. kita bisa menggunakan pernyataan throw dengan sintaks : throw objek_pengecualian. biasanya objek tersebut dibuat dengan operator new. (Pernyataan try harus memiliki satu klausa finally atau catch). misalnya : throw new ArithmeticException("Pembagian dengan nol"). meskipun jika perintah hanya terdiri dari satu perintah. Untuk melempar pengecualian. . Pada dasarnya klausa finally dimaksudkan untuk melakukan langkah pembersihan yang tidak boleh dihilangkan. Dalam banyak kasus. Sintaks dari klausa catch adalah: catch (nama_kelas_pengecualian nama_variabel) { pernyataan } dan sintaks klausa finally adalah finally { pernyataan } Semantik dari klausa finally yaitu pernyataan di dalam klausa finally akan dijamin untuk dilaksanakan sebagai perintah akhir dari pernyataan try. Pernyataan try boleh tidak dimasukkan.

4*A*C. Pengecualian ini ditangani dengan cara yang sama. maka pengolahan pengecualian akan berlanjut. Pengecualian tersebut telah ditangani. jika subrutin tersebut dipanggil di dalam pernyataan try dan memiliki klausa catch yang cocok. double B. Pengecualian akan menghentikan program secara keseluruhan jika keseluruhan rantai panggil subrutin hingga main() tidak menangani pengecualian tersebut. // (Lempar pengecualian jika A == 0 atau B*B-4*A*C < 0. Misalnya : static double akar(double A. Setelah menangani pengecualian tersebut. Kemudian rutin yang memanggil subrutin tersebut memiliki kesempatan untuk menangani pengecualian tersebut. Kemudian program akan melanjutkan program seperti biasa. Pengecualian bisa dilempar baik oleh sistem (karena terjadinya kesalahan) atau oleh pernyataan throw. Artinya. } else { double diskriminan = B*B . Misalnya suatu pengecualian dilempar dari pernyataan try. jika ada. Suatu subrutin yang mungkin melempar pengecualian dapat memberi tahu dengan menambahkan klausa "throws nama_kelas_pengecualian" pada definisi suatu subrutin.Parameter dalam konstruktor adalah pesan kesalahan dalam objek pengecualian. Jika pernyataan try tersebut memiliki klausa catch untuk menangani tipe pengecualian tersebut. maka subrutin tersebut akan dihentikan (setelah menjalankan klausa finally. jika tersedia). rutin tersebut akan dihentikan dan rutin yang memanggilnya akan mencoba menangani pengecualian tersebut. maka klausa ini akan melompat ke klausa catch dan menjalankan perintah di dalamnya. komputer akan menjalankan klausa finally. maka klausa catch tersebut akan dieksekusi dan program akan berlanjut seperti biasa. if (diskriminan < 0) . double C) throws IllegalArgumentException { // Menghasilkan akar yang lebih besar // dari persamaan kuadrat A*x*x + B*x + C = 0. Jika suatu pengecualian tidak ditangkap dan ditangani.) if (A == 0) { throw new IllegalArgumentException("A tidak boleh nol. Lagi-lagi jika rutin tersebut tidak menangani pengecualian tersebut. Jika pengecualian dilempar pada saat eksekusi suatu subrutin dan pengecualian tersebut tidak ditangani di dalam subrutin yang sama.").

Jika tidak. Jika suatu subrutin bisa melempar pengecualian seperti ini. maka klausa [code]throws harus ditulis pada definisi subrutin. Di sisi lain. maka Java akan menganggap sebagai kesalahan sintaks. Jika kita tidak menangani pengecualian tersebut dengan cara-cara di atas. maka program akan crash dan programmer akan tahu apa yang harus diperbaiki. Kemudian program yang memanggil rutin tersebut bebas untuk menangkap atau membiarkan pengecualian yang dilempar oleh rutin tersebut. Penanganan Pengecualian Wajib Dalam contoh-contoh sebelumnya. Atau dengan menambahkan klausa throws di kepala definisi subrutin. program tersebut dapat menangkapnya. maka compiler akan menampilkan kesalahan sintaks. return (-B + Math. misalnya suatu pernyataan dalam program dapat melemparkan pengecualian yang mewajibkan penanganan pengecualian. JIka tidak. Jika program yang memanggil subrutin tersebut mengetahui bagaimana cara yang tepat untuk menangani pengecualian tersebut."). siatuasinya sedikit berbeda. . Menangani IllegalArgumentException bukan sesuatu yang "wajib" dilakukan. yaitu : Menggunakan pernyataan try yang memiliki klausa catch untuk menangani pengecualian tersebut.</p><p>Untuk kelas pengecualian yang mewajibkan penanganan pengecualian. maka subrutin lain yang memanggil subrutin kita akan bertanggung jawab menangani pengecualian tersebut. mendeklarasikan subrutin akar() yang dapat melempar pengecualian IllegalArgumentException adalah sesuatu yang "sopan" untuk pembaca rutin tersebut. } } Seperti kita diskusikan pada bagian sebelumnya. Subrutin akan melempar pengecualian dengan tipe IllegalArgumentException jika salah satu dari kondisi awal ini tidak dipenuhi.throw new IllegalArgumentException("Diskriminan < nol. Subruin dapat melempar IllegalArgumentException tanpa mengumumkan kemungkinan tersebut. melempar pengecualian kadang kala menjadi pilihan yang lebih bijaksana. Pernyataan tersebut bisa berasal dari pernyataan throw yang sengaja dilemparkan atau hasil dari pemanggilan suatu subrutin yang melempar pengecualian tersebut. Jika klausa throws digunakan. Begitu juga halnya dengan tipe NullPointerException[/code. programmer bebas untuk menangkap atau mengabaikan pengecualian tersebut. Jika kondisi ilegal ditemukan dalam suatu subrutin. perhitungan dalam subrutin ini memiliki kondisi awal di mana A != 0 dan B*B-4*A*C >= 0. Pengecualian ini harus ditangani dengan salah satu dari dua cara.sqrt(diskriminan)) / (2*A).

jika tidak ada kelas standar yang cukup mewakili jenis pengecualian tersebut. program akan melempar pegecualian. Kelas baru tersebut harus diturunkan dari kelas standar Throwable atau kelas turunannya. programmer dapat membuat turunan dari kelas Exception atau salah satu kelas turunannya. Tanpa pengecualian. Dalam beberapa kasus. Akan tetapi. di mana kasus-kasus pengecualian akan ditangani di bagian lain. Pemrograman dengan Pengecualian Pengecualian bisa digunakan untuk membantu kita menulis program tangguh. Pengecualian adalah pendekatan yang terstruktur dan terorganisir untuk membuat program tangguh. seperti IllegalArgumentException atau IOException. programmer bisa membuat kelas pengecualian baru. Di antara pengecualian yang mewajibkan penanganan pengecualian adalah yang berhubungan dengan rutin input/output. Berikut ini adalah contoh suatu kelas yang merupakan turunan dari kelas Exception yang mewajibkan penanganan kesalahan apabila ia dilemparkan : public class KelasahanBaca extends Exception { public KelasahanBaca(String pesan) { // Konstruktor. Misalnya. kita bisa menulis program yang algoritma yang lebih jelas. Desain Java tidak memungkinkan programmer untuk mengabaikan kondisi tersebut. Untuk membuat kelas pengecualian baru yang mewajibkan penanganan kesalahan. Pengecualian yang wajib biasanya merupakan kondisi yang berada di luar jangkauan programmer. yaitu di dalam klausa catch. kelas baru merupakan turunan dari kelas RuntimeExceptionatau kelas turunannya jika programmer tidak mewajibkan penanganan kesalahan. Artinya kita tidak boleh menggunakan rutin ini jika kita mengetahui bagaimana menangani pengecualian. mungkin akan lebih mudah apabila pengecualian yang dilemparkan merupakan objek dari salah satu kelas pengecualian bawaah Java. Secara umum. Bagian berikutnya akan membahas tentang contohcontoh input/output dan penanganan pengecualian dengan lebih gamblang.Penanganan pengecualian menjadi wajib untuk kelas yang bukan kelas turunan dari Error atau RuntimeException. Program tangguh harus bisa menangani kondisi seperti ini. Membuat Kelas Pengecualian Baru Ketika suatu program menemukan kondisi yang tidak biasa dan tidak ada cara yang masuk akal untuk ditangani pada saat itu juga. input ilegal atau aksi ilegal oleh user. program akan dipenuhi dengan pernyataan if untuk menguji berbagai macam kondisi kesalahan. . Membuat objek dari KesalahanBaca yang berisi // pesan kesalahan super(pesan). Dengan pengecualian.

} } Kelas tersebut hanya memiliki konstruktor sehingga kita bisa membuat objek dari kelas KesalahanBaca yang berisi pesan kesalahan. yaitu Exception."). yaitu dengan menambah klausa "throws KesalahanBaca".getMessage() akan mengambil pesan kesalahan yang diberikan pada konstruktornya. misalnya : throw new ParseError("Ditemukan bilangan negatif ilegal. Misalnya try { ambilNamaUser(). maka subrutin yang melemparnya harus dideklarasikan di awal bahwa subrutin tersebut bisa melempar KesalahanBaca.. Misalnya : void ambilNamaUser() throws KesalahanBaca { .").. Lihat bagian sebelumnya). olahNamaUser(). ini berarti jenis kesalahan tertentu telah terjadi. Jika pernyataan throw tidak terdapat dalam pernyataan try yang menangkap kesalahan tersebut. Tentunya kelas tersebut juga mewariskan metode getMessage() dan printStackTrace() dari kelas supernya. } catch (KesalahanBaca kb) { . } Klausa ini tidak diperlukan apabila KesalahanBaca didefinisikan sebagai turunan dari kelas RuntimeException. Konstruktor objek ini harus memiliki pesan kesalahan. Jika e merujuk pada objek dengan tipe KesalahanBaca maka perintah e. (Pernyataan "super(pesan)" memanggil konstruktor di kelas supernya. Apabila objek dengan tipe KesalahanBaca dilempar. (Mungkin misalnya terjadi apabila pembacaan suatu String yang diproses program tidak sesuai dengan format yang diharapkan). Pernyataan throw bisa digunakan untuk melempar kesalahan dengan tipe KesalahanBaca. Suatu subrutin yang ingin menangani KesalahanBaca dapat menggunakan pernyataan try dengan klausa catch untuk menangkap KesalahanBaca. atau throw new ParseError("Kata '" + word + "' bukan nama file yang benar. karena pengecualian ini tidak wajib untuk ditangani.

yang bisa digunakan dalam perintah berikut: if ( kapalUser. kapal = k.y pada layar super(pesan). Kapal k. Dalam hal ini orang yang menulis subrutin . // Kapal yang meledak int lokasi_x. xLok. misalnya : class KapalMeledak extends RuntimeException { Kapal kapal. lokasi_y = y. Ingat bahwa kondisi objek KapalMeledak mungkin bukan suatu kesalahan. } } Di sini. maka klausa catch dalam bentuk "catch (Exception e)" juga akan menangkap KesalahanBaca dan juga objek yang bertipe Exception. yLok). Kelas dan Subrutin Pengecualian Kemungkinan untuk melempar pengecualian akan berguna dalam penulisan subrutin dan kelas umum yang digunakan oleh lebih dari satu program. lokasi_x = x.isTertembak() ) throw new KapalMeledak("Anda Tertembak!".. Mungkin hanya merupakan jalan lain dari alur suatu game. objek KapalMeledak berisi pesan kesalahan dan informasi tambahan tentang kapal yang meledak. kapalUser. // Lokasi tempat kapal meledak KapalMeledak(String pesan. . . ada gunanya untuk menyimpan data dalam objek pengecualian. Pengecualian bisa juga digunakan sebagai percabangan besar seperti ini dengan cara yang lebih rapi. // Tangani kesalahan } Ingat bahwa karena KesalahanBaca adalah kelas turunan dari Exception. int y) { // Konstruktor: Buat objek KapalMeledak yang menyimpan // pesan kesalahan dan informasi bahwa kapal k // meledak pada lokasi x. int x. Kadang-kadang. lokasi_y.

kita tidak ingin program kita crash.atau kelas tersebut tidak memiliki cara yang umum untuk menangani kesalahan tersebut. Bahasa pemrograman seperti C dan C++ memiliki fasilitas untuk menambah asersi (assertions) dalam program. cara ini hanya efektif jika program utama mengecek nilai keluarannya. Asersi dapat berbentuk assert(kondisi). Akan tetapi banyak program yang dibuat pada dasarnya seperti try { . fungsi ambilDouble() bisa saja mengembalikan nilai NaN jika input dari user salah. Terutama karena ia tidak tahu bagaimana subrutin atau kelas tersebut akan digunakan. Ketika komputer menemukan asersi dalam eksekusi suatu program. di mana kondisi adalah ekspresi bernilai boolean. Dalam hal ini. akan tetapi cara ini tidak memuaskan karena mungkin akan ada masalah di kemudian hari. Dalam kondisi seperti itu. programmer pemula biasanya lebih memilih untuk mencetak pesan kesalahan dan melanjutkan program. ada kemungkin bahwa suatu kondisi awal mungkin tidak bisa dipenuhi. akan lebih baik jika kita letakkan pernyataan if untuk mengujinya. ia akan mengevaluasi kondisi tersebut. maka program akan berhenti. Kita bisa mengganti pesan kesalahan dengan pesan yang lebih baik. Program yang memanggil subrutin atau menggunakan kelas tersebut perlu tahu bahwa suatu kesalahan telah terjadi. Kondisi adalah suatu kondisi awal yang harus benar pada satu titik di dalam program. Asersi dalam bentuk ini tidak tersedia pada Java. Untuk itu. Akan tetapi. Setelah kita merilis program kita. maka program akan terus berjalan. Pengecualian akan lebih rapi jika suatu subrutin memiliki cara untuk tahu apabila suatu kesalahan telah terjadi. Bentuk asersi assert(kondisi) dapat diganti dalam bahasa Java dalam bentuk : if (kondisi == false) throw new IllegalArgumentException("Asersi gagal. satu-satunya alternatif adalah mengembalikan nilai khusus atau mengeset nilai variabel tertentu untuk memberi tahu bahwa suatu kesalahan telah terjadi. Jika kondisi tersebut salah. Jika benar. Dalam bahasa yang tidak memiliki pengecualian. akan tetapi sesuatu yang mirip seperti ini bisa dilakukan dengan pengecualian. Mencetak pesan kesalahan dan menghentikan program juga bukan solusi karena program tidak berkesempatan untuk mengatasi kesalahan tersebut. Misalnya. Asersi Ingat bahwa kondisi awal adalah kondisi yang harus benar pada suatu titik di dalam program sehingga program akan berjalan benar dari titik tersebut dan seterusnya. Asersi sangat umum digunakan dalam pengujian dan debugging."). dan mungkin akan lebih cantik apabila kelas pengecualiannya juga diganti dengan kelas yang lebih spesifik. Pertanyaan berikutnya adalah apa yang harus kita lalukan jika kondisi awal tidak benar? Salah satunya adalah melempar pengecualian. yang kemudian akan menghentikan program kecuali jika pengecualian tersebut ditangkap dan ditangani di tempat lain.

out."). Dalam arti jika program dikompilasi dengan cara lain. maka asersi akan dibuang dari dalam program utama. Versi rilis dari program dikompilasi dengan asersi yang dimatikan. Karena nilai if ini akan selalu bernilai false. Ada cara seperti ini yang mungkin juga bisa diterapkan pada Java. System. kompiler canggih akan mengabaikan perintah ini dalam hasil kompilasinya. maka nilai "DEBUG == true && kondisi == false" sama dengan nilai kondisi. Keuntungan lainnya adalah kita tidak perlu membuang asersi tersebut dari kode sumber programnya.println("Harap kirimkan pesan bug kepada programmernya. Salah satu keuntungan asersi pada C dan C++ adalah asersi bisa "dimatikan". dan kompiler canggih akan bisa mendeteksi ini pada saat kompilasi. Dengan cara ini versi rilis akan lebih efisien.printStackTrace().out. dan kita menulis asersi seperti if (DEBUG == true && kondisi <span style="color: #00bb00. } Jika suatu program memiliki banyak asersi.println("Pengecualian dalam program terjadi. Sekarang misalnya kita telah selesai melakukan debugging.out. karena if ini . nilai "DEBUG == true && kondisi == false" selalu bernilai false. // Jalankan program . kita ganti definisi DEBUG menjadi static final boolean DEBUG = false. Sebelum kita mengkompilasi versi rilis suatu program. karena komputer tidak perlu mengevaluasi semua asersi tersebut. yang tergantung dari seberapa canggih kompiler kita. Sekarang. Misalnya kita tentukan suatu konstanta static final boolean DEBUG = true. System. Karena DEBUG bernilai true.println("Detail kesalahan:"): e. maka akan menyebabkan program lebih lambat."). . sehingga pernyataan if ini sama dengan pengujian suatu kondisi awal. } catch (Exception e) { System.."></span>== false) throw new IllegalArgumentException("Asersi Gagal.").

misalnya kita bisa membuat array yang berisi semua komponen dalam applet. Juga mencakup kelas standar java. Bab VIII . Item dalam array bisa bertipe salah satu tipe Java primitif. suatu array berisi 100 bilangan bulat. Pengurutan dan Rekursi Struktur Data Berantai Array Array adalah struktur data yang terdiri dari item berurutan. sehingga. Item-item ini bisa juga berupa referensi ke objek.Pengenalan Struktur Data dan Algoritma Komputer bisa menjadi canggih seperti sekarang karena struktur data. Dalam banyak hal. yang nilainya ditentukan pada saat array tersebut dibuat. tapi tipe struktur data seperti ini -. Struktur data sederhana seperti ini bisa berupa array atau record. Istilah "record" sebetulnya tidak digunakan pada Java. data struktur yang cocok hanya terdiri dari kumpulan data berurutan. Misalnya. Hasilnya. Suatu objek adalah struktur data. yaitu dengan menghubungkan objek satu sama lain.util. • • • Array Pencarian. Dan kita hanya cukup mengganti satu baris saja pada kode sumbernya. Dalam Java.yang memiliki sedikit variabel instansi -. Bagian ini akan membahas bagaimana array dibuat dan digunakan pada Java. akan tetapi dalam banyak aplikasi. • • • • • Membuat dan Menggunakan Array Pemrograman dengan Array Array Dinamis ArrayLists dan Vector Array Multi Dimensi Membuat dan Menggunakan Array Jika sekumpulan data digabungkan dalam satu unit.hanya awalnya saja. programmer akan membuat struktur data kompleksnya sendiri. Struktur dala adalah koleksi dari suatu data yang saling berhubungan. item dalam array selalu dinomori dari nol hingga nilai maksimum tertentu. Suatu objek bertipe ArrayList sangat mirip dengan array dari Object. akan tetapi ia bisa bertambah ukuran secara dinamis. di mana semua itemnya bertipe sama.tidak akan pernah dieksekusi. kode ini tidak akan dimasukkan ke dalam versi rilis program. yang dinomori dari nol hingga 99. Beberapa bahasa . Suatu record pada intinya mirip dengan objek pada Java yang hanya memiliki variabel instansi tanpa metode instansi. Bab ini akan membahas tentang array dan beberapa struktur data dalam Java. Data struktur dapat berupa struktur yang sangat kompleks. hasilnya adalah suatu struktur data.ArrayList.

Masing-masing item disebut nama field. adalah variabel instansi suatu objek -. tanggalLahir dan umur. kelas Orang didefisikan sebagai : class Orang { String nama. . int. nomorID.pemrograman lain yang tidak mendukung objek biasanya mendukung record. ada dua kemungkinan kegunaan variabel : sebagai nama suatu lokasi di memori. Dalam Java. Suatu array bertipe String disebut "array String". maka panjangnya tidak bisa diubah lagi. Date tanggalLahir. Elemen array pada dasarnya adalah variabel instansi dalam objek array. Nama fieldnya adalah nama. Seperti objek lain. Nomor posisi dari array disebut indeks item tersebut dalam array. maka indeks elemen terakhir adalah N-1. variabel hanya bisa merujuk pada array. Lihat bahwa tipe datanya berbeda-beda yaitu String. Seperti record. misalnya. } maka objek dari kelas Orang bisa disebut juga sebagai record dengan 4 field. Jika panjang array adalah N. elemen array selalu dinomori mulai dari nol. dan field yang berbeda dapat berupa tipe yang berbeda. atau nama interface. Tipe dasar suatu array bisa berupa tipe Java apa saja. Isinya bisa diganti kapanpun. Misalnya. Dalam bahasa C yang bukan bahasa berorientasi objek. Tipe dari item tersebut disebut tipe dasar dari array. Akan tetapi array bukan urutan int atau urutan String atau urutan nilai bertipe apapun. Dalam Java. Semua item pada array harus bertipe sama. di mana seperti kelas lain adalah kelas turunan dari kelas Object. Variabel lain yang bisa merujuk array juga bisa bernilai null yang berarti ia tidak merujuk pada lokasi memori apapun.disebut field suatu record.dalam Java. Nilai tersebut disimpan di dalam array. Lebih baik jika array adalah urutan variabel bertipe int atau String atau tipe lainnya. dan Date. item pada record dipanggil dengan nama. Data pada record -. maka array tersebut disebut "array int". Seperti biasa. dan nama suatu nilai yang disimpan pada lokasi memori. Akan tetapi. array juga bagian dari suatu kelas. Jika tipe dasar suatu array adalah int. memiliki tipe data record. Perbedaan sifat dari suatu record adalah bahwa item pada record dipanggil berdasarkan namanya. kecuali mereka dipanggil dalam indeksnya bukan namanya. nama field adalah nama variabel instansi. baik berupa tipe primitif. Array merupakan kontainer bukan kumpulan nilai. Array harus dibuat dengan operator new. Setiap posisi pada array bersifat seperti variabel. int nomorID. dan masing-masing item dipanggil besarkan nomor posisi pada array tersebut. int umur. Yaitu. Dalam Java. array adalah objek. Item pada array (maksudnya setiap anggota variabel dalam array tersebut) sering juga disebut elemen array. suatu array adalah kumpulan item. Definisi suatu array adalah : kumpulan item bernomor yang semuanya bertipe sama. Variabel tidak bisa menyimpan array. Sekali array dibuat. Ada beberapa konsekuensi yang lahir dari fakta ini. Jumlah item dalam suatu array disebut panjang array. kita tidak akan bahas lebih lanjut di sini. indeks dari elemen pertama suatu array adalah nol. Setiap posisi dapat menyimpan nilai dengan tipe tertentu (yaitu tipe dasar array). sedangkan item pada array dinomori. dimana pada C disebut "struct". nama kelas. Karena record hanya merupakan bagian lebih kecil dari objek.

akan tetapi nilai awalnya adalah null (jika merupakan variabel anggota suatu kelas) atau tak tentu (jika merupakan variabel lokal di dalam suatu metode). Jika nama suatu tipe adalah TipeDasar." dapat diilustrasikan sebagai berikut . Mungkin perlu juga dijelaskan bahwa jika KelasA adalah kelas turunan dari KelasB maka KelasA[] otomatis menjadi kelas turunan KelasB[]. ayng kemudian bisa diberikan kepada daftar. dan bisa diberikan sebagai parameter pada subrutin. Nilai N di dalam kurung menyatakan panjang array. membuat array 5 buah integer. Dari kelas yang bernama String diturunkan tipe array String[]. Kita bisa memberinya nilai. maka nama kelas arraynya adalah TipeDasar[]. Sintaksnya sama seperti sintaks sebelumnya. Tipe dasar suatu array dapat berupa tipe apapun yang ada atau sudah didefinisikan pada Java. Misalnya A adalah variabel yang merujuk pada suatu array. sehingga array tahu berapa panjangnya. Untuk sekarang ingat sintaks berikut variabel_array [ekspresi_integer] untuk merujuk pada suatu array. yang membuat variabel bernama daftar dengan tipe int[]. Meskipun setiap array merupakan suatu objek. maka kelas array dari tipe tersebut otomatis ada. kelas array tidak harus didefinisikan sebelumnya. Item pertama adalah A[0]. Artinya. "TipeDasar[]" dibaca seperti "array TipeDasar". dan seterusnya. maka kita bisa menggunakannya untuk mendeklarasikan variabel. atau jumlah elemen yang bisa ditampung. yaitu : daftar = new int[5]. Maka indeks k di dalam A bisa dipanggil dengan A[k]. A[k] adalah suatu variabel dan bisa digunakan seperti variabel lainnya. dan ada beberapa fitur khusus Java untuk membuat dan menggunakan array. Misalnya tipe primitif int akan diturunkan kelas array int[].Meskipun array berupa objek. Operator new digunakan untuk membuat objek array baru. Semuanya akan didiskusikan di bawah nanti. konstruktor "new TipeDasar[N]" digunakan untuk membuat array bertipe TipeDasar[]. suatu objek yang diciptakan dari kelas TipeDasar[] adalah array dari item yang tiap itemnya bertipe TipeDasar. Variabel ini bisa menunjuk pada array int.length (akan tetapi kita tidak bisa mengubahnya) Hasil dari pernyataan "daftar = new int[5]. Setiap elemen di dalam array int[] adalah variabel yang memiliki tipe int dan bisa diisi dengan nilai dengan tipe int. Misalnya. Nilai ini bisa null atau referensi ke objek yang bertipe String (dan juga kelas turunan dari String) Mari kita lihat contoh lebih konkrotnya menggunakan array bilangan bulat sebagai contoh pertama kita. int[] daftar. Tanda kurung "[]" dimaksudkan untuk mengingat sintaks untuk mengambil item di dalam suatu array. Kita bisa mendapatkan panjang suatu array. Karena int[] adalah sebuah kelas. Jika suatu tipe telah ada. yang kedua adalah A[i]. misalnya daftar menggunakan daftar. Setiap elemen di dalam array String[] adalah variabel dengan tipe String. Lebih umum lagi. bisa menggunakannya dalam ekspresi. Panjang array adalah variabel instansi di dalam objek array. ada beberapa perbedaan antara array dan objek lainnya. yang bisa diisi dengan nilai bertipe String.

i < daftar. kita harus selalu ingat bahwa kedua kesalahan tersebut mungkin terjadi. Ambil nilai k. sehingga kondisi lanjutan "i < daftar. Ikuti pointer ini untuk mencari objek array. . Ketika kita menggunakan array dalam program. i++) { System.length. kesalahan indeks array keluar batas adalah kesalahan yang lebih sering terjadi.length" tidak lagi benar. Kemungkinan kesalahan kedua adalah jika daftar merujuk pada suatu array. Misalnya nilai daftar adalah null. daftar[3]. daftar[k] berarti : "Ambil pointer yang disimpan di dalam variabel daftar. daftar[1]. Misalnya jika idks adalah variabel bertipe int. false untuk boolean. dan di sanalah alamat memori yang Anda ingin. Ini adalah contoh umum dari menggunakan perulangan untuk mengolah suatu array. Elemen di dalam array daftar dapat dirujuk dengan daftar[0]. karakter dengan nilai Unicode 0 untuk char dan null untuk objek. Untuk komputer. Penggunaan suatu variabel dalam suatu program menyatakan lokasi di memori. Kasus ini akan menampilkan pesan kesalahan "pointer kosong". referensi array sebetulnya lebih umum lagi. Contoh berikut akan mencetak semua isi integer di dalam array daftar ke layar : for (int i = 0. dan daftar[i] merujuk pada daftar[0]. dan daftar[4] (ingat juga bahwa nilai indeks terbesar adalah panjangnya array dikurang satu).Perlu dicatat bahwa array integer secara otomatis diisi dengan nol. Jadi nilai yang disimpan pada variabel daftar[0] akan dicetak ke layar. Percobaan merujuk suatu elemen pada suatu array kosong adalah suatu kesalahan. maka daftar tidak memiliki referensi sama sekali.println( daftar[i] ). Perulangan kedua adalah i = 1. Akan tetapi. } Perulangan pertama adalah ketika i = 0. Dalam Java. akan tetapi k berada di luar rentang indeks yang legal. Komputer harus menentukan lokasi memori di mana ia dijadikan referensi. Tanda kurung di dalam referensi array bisa berisi ekspresi apapun yang nilainya suatu integer.out. Ini akan terjadi jika k < 0 atau jika k >= daftar. Dalam kasus ini." Ada dua hal yang bisa salah di sini. sehingga nilai daftar[i] dicetak. array yang baru dibuat akan selalu diisi dengan nilai tertentu: nol untuk angka. daftar[2].length. Pergi ke posisi ke-k dari array tersebut. Dari kedua kasus di atas. maka daftar[idks] dan daftar[2*idks+3] secara sintaks benar. Pikirkan sesaat tentang apa yang akan komputer lakukan ketika ia menemukan referensi ke elemen suatu array daftar[k] ketika program berjalan. Perulangan berhenti setelah mencetak daftar[4] dan i menjadi sama dengan 5. Kasus ini disebut kesalahan "indeks array keluar batas".

karena kita memberikan 7 nilai awal kepada array ini. Dalam pernyataan yang untuk membuat array.pink. seperti variabel lainnya.Untuk suatu variabel array.red. Yaitu menggunakan jenis lain dari operator new untuk membuat atau menginisialisasi objek array baru. daftar = new int[5]. akan membuat array baru yang berisi 7 nilai.blue.g. 343 }. Sintaks umum dari bentuk operator new seperti ini adalah new TipeDasar [ ] { daftar_nilai_nilai } . dan mengisi daftar dengan referensi ke array baru tersebut. 27. 9. karena secara implisit sudah bisa ditentukan dari jumlah daftar angkanya. 64.255). (Jika daftar adalah variabel instansi.b). Elemen di dalam penginisialisasi array tidak harus selalu berbentuk konstanta. 9. 4. 36." karena ini hanya bisa dilakukan di dalam subrutin) Array yang baru dibuat akan diisi dengan nilai awal yang tergantung dari tipe dasar array tersebut seperti dijelaskan sebelumnya. Misalnya untuk memberi nilai kepada suatu variabel daftar. Jika daftar merupakan variabel lokal dalam subrutin. new Color(180. yaitu 1. Panjang array tersebut tidak perlu diberikan.white }. daftar = new int[5]. akan tetapi tidak bisa digunakan seperti operator pemberi nilai (=) di tengah-tengah suatu program. Akan tetapi Java juga menyediakan cara untuk memberi isi array baru dengan daftar isinya. dan seterusnya. Akan tetapi ada cara lain yang bisa digunakan sebagai pernyataan pemberian nilai atau diberikan ke dalam subrutin. 125.black. // biru muda Color. misalnya : int[] daftar = new int[5]. Nilai daftar[0] berisi 1. Suatu penginisialisasi array memiliki bentuk daftar angka yang dipisahkan dengan koma dan diapit dengan tanda kurung kurawal {}. Inisialisasi array bentuk seperti ini hanya bisa digunakan dalam deklarasi suatu variabel baru. 16. Panjang daftar adalah 7.0). (Cara ini agak kaku dengan sintaks aneh.green. kita bisa mendeklarasikan dan mengisinya dengan satu langkah sekaligus. tentukan kita tidak bisa mengganti "int[] daftar = new int[5]. 8. maka perintah di atas akan persis sama dengan dua perintah : int[] daftar. 25. Color. deklarasi berikut membuat array dari delapan jenis Color beberapa warna telah dibentuk dengan ekspresi "new Color(r. nilai daftar[1] berisi 4.180. 49 }. Juga bisa merupakan variabel atau ekspresi apa saja.180. kita bisa menggunakan : daftar = new int[] { 1. 16. asalkan nilainya bertipe sama dengan tipe dasar array tersebut." Color[] palette = { Color. // hijau gelap Color. Misalnya. ini bisa dilakukan dengan menggunakan penginisialiasi array (array initializer). 36." dengan "int[] daftar. Color. 216. seperti halnya sintaks kelas anonim yang telah didiskusikan sebelumnya). new Color(0. 25. Color. 4. dan 49. misalny : int[] daftar = { 1.

maksudnya adalah mendeklarasikan variabel dengan tipe tertentu dan namanya adalah int[].1 Lihat bahwa kondisi kelanjutan "i < A.. "Jalan". (proses elemen kedua di dalam A) . Dua jenis teknik pengolahan array -. "Sebelum" } ). // tambah A[i] ke dalam jumlah untuk i = 0. dan bisa digunakan untuk banyak situasi di mana suatu objek dengan tipe TipeDasar dipentingkan. pengolahan array berarti menggunakan operasi yang sama kepada setiap elemen di dalam array. // proses A[i] } Misalnya. atau mungkin lebih baik dihindari. Pemrograman dengan Array Array merupakan jenis struktur data yang sangat dasar dan sangat penting. maka kita bisa menuliskan buatTombol( new String[] { "Stop". .length. Tambah A[0]. Tambah A[ A. Akan tetapi sintaks alternatif ini tidak begitu masuk akan dalam Java. Ingat bahwa kita menggunakan "<" bukan "<=" karena dengan "<=" komputer akan memberikan kesalahan indeks di luar batas. "Berikut".length" menyatakan bahwa nilai i terakhir yang akan diolah adalah A. (proses elemen terakhir di dalam A) Dengan menggunakan pengetahuan yang kita telah pelajari tentang perulangan. Biasanya sering dilakukan dengan perulangan for. Pada akhirnya. i++) { . A. A adalah array dengan tipe double[].1 ].length . di mana sintaks tersebut digunakan dalam bahasa C dan C++.akan dibahas kemudian. 1. Misalnya kita ingin menjumlah semua nilai dalam array tersebut. Kita akan lihat beberapa contohnya.length. . i < A. // Mulai dengan 0 for (int i = 0. i++) jumlah += A[i]. Perulangan untuk mengolah semua elemen dalam array A dapat ditulis dalam bentuk : // lakukan inisialiasi yang diperlukan sebelumnya for (int i = 0. (proses elemen pertama di dalam A) Tambah A[1]. Di sini perulangan akan menghitung banyaknya elemen di dalam array A yang nilainya kurang dari nol : int hitung. Dalam banyak hal.. i < A. // Jumlah nilai di dalam A jumlah = 0. Lagian. . akan bernilai sama dengan int daftar[]. Misalnya buatTombol merupakan metode yang mengambil array String sebagai parameter. // Untuk menghitung elemen .length .length .Ini adalah suatu ekspresi yang isinya merupakan objek. Catatan terakhir : untuk alasan sejarah. . maka deklarasi int[] daftar.1 yaitu elemen terakhir dalam array. Akan lebih masuk akan untuk mengikuti siintaks "nama_tipe nama_variabel" seperti pada bentuk bertama. nanti Anda akan bisa membuat perulangan seperti di atas di luar kepala. Bagian ini akan memperkenalkan beberapa ide dasar pengolahan array secara umum. . Teknik pengolahan array merupakan teknik pemrograman yang paling penting yang kita harus kuasai. Algoritma umum untuk melakukannya adalah : Mulai dengan 0. kita bisa ubah algoritma di atas menjadi bentuk perulangan for seperti berikut: double jumlah..pencarian dan pengurutan -.

sehingga // Buat objek array baru. baru kemudian melihat isi elemen array lainnya mulai dengan A[1]. Kita bisa mengganti "A[i] < 0. Lagian apa artinya mencari nilai terbesar di dalam suatu array yang panjangnya nol?) Contoh terakhir dari operasi array. } // Di sini maks berisi nilai elemen array yang paling besar (Ada masalah yang lebih penting di sini. Setelah semua elemen array diproses. double maks = A[0]. karena perintah ini tidak membuat objek array baru. Java membolehkan array memiliki panjang nol. (Sehingga perubahan yang terjadi pada A[i] akan juga menyebabkan B[i] berubah). Misalnya kita ingin menghitung banyaknya elemen di dalam array A yang sama dengan elemen sesudahnya. yang panjangnya sama dengan panjang A double[] B = new double[A. Untuk mengkopi array A. karena tidak ada lagi array sesudahnya. . Pertanyaannya adalah.0" jika kita ingin menghitung banyaknya elemen di dalam array yang memiliki sifat tertentu. catat nilai terbesar saat itu. Elemen setelah A[i] adalah A[i+1].length]. tidak cukup untuk menggunakan perintah double[] B = A. Sehingga kita harus berhenti satu elemen sebelum array terakhir. kita harus membuat objek array baru. sehingga memanggil A[0] akan menghasilkan kesalahan indeks keluar batas. Akan tetapi tunggu dulu : Tes ini tidak bisa digunakan apabila A[i] adalah elemen terakhir dalam array. Kita akan simpan nilai terbesar yang kita temui dalam variabel maks. apa nilai awal maks? Salah satu kemungkinannya adalah mulai dengan nilai maks sama dengan A[0]. Akan tetapi array biasanya array dengan panjang nol biasanya sesuatu yang kita ingin hindarkan dalam kehidupan sehari-hari.length . // Mulai dengan nol for (int i = 0. i < A.1. misalnya kita ingin mengkopi suatu array. maka maks merupakan nilai elemen terbesar di dalam array tersebut. Yang dibuat di sini adalah variabel baru yang merujuk pada objek yang sama dengan A. sehingga menjadi int hitung = 0. Komputer akan menolak pernyataan ini. Misalnya. i < A. i < A. } Masalah umum lainnya adalah mencari nilai terbesar di dalam array A.0) // Jika elemen ini kurang dari nol hitung++. Variasinya akan memiliki tema yang sama. Pada saat kita melihat elemen array satu per satu. i++) { if (A[i] == A[i+1]) hitung++. Strateginya adalah lihat semua isi array. sehingga kita bisa mengganti klausa if dengan "if (A[i] == A[i+1])". kapanpun kita melihat nilai elemen tersebut lebih besar dari maks kita akan mengganti nilai maks dengan nilai yang lebih besar tersebut. // tambah hitung dengan 1 } // Di sini nilai "hitung" adalah banyaknya elemen yang kurang dari 0. i++) { if (A[i] < 0. // lihat kondisi for berubah dibandingkan dengan contoh sebelumnya for (int i = 0.length.length. i++) { // i mulai dari elemen kedua if (A[i] > maks) max = A[i].hitung = 0. Untuk membuat array baru yang merupakan kopi dari array A. Artinya bahkan A[0] pun tidak ada di dalam array. dan mengkopi isinya satu per satu dari array A ke array baru. // nilai maks berisi elemen array pertama for (int i = 1.

Misalnya. public class CLDemo { public static void main(String[] args) { System. yang merupakan subrutin anggota statik dari kelas standar System. i++) B[i] = A[i]. Deklarasinya memiliki bentuk seperti : public static void arraycopy(Object arraySumber.arraycopy( sumber. maka user bisa menjalankan kelas tersebut dengan perintah "java programKu" di konsol. Object arrayTujuan. string di dalam array ini adalah parameter dari baris perintah. Misalnya kita akan mengkopi array A.length ).length]. maka kita bisa menggunakan perintah double B = new double[A. jumlah adalah berapa banyak elemen yang akan dikopi.arraycopy( A. user harus mengetikkan perintah untuk menjalankan program. Jika kita tulis dengan "java programKu satu dua tiga". 0. B. int indeksAwalTujuan. sehingga kita bisa menggunakannya seperti tipe-tipe Java lainnya. sumber. Nilai akan dikopi dari arraySumber mulai dari posisi indeksAwalSumber dan akan disimpan pada arrayTujuan mulai dari posisi indeksAwalTujuan. Termasuk juga digunakan sebagai parameter formal di dalam suatu subrutin.length ). Misalnya. Nilai akan dikopi dari arraySumber ke arrayTujuan. 0. Sistem akan memasukkan parameter-parameter ini ke dalam array String[] dan memberikan array ini pada rutin main(). Berikut ini adalah contoh program sederhana yang hanya mencetak parameter dari baris perintah yang dimasukkan oleh user. // Kopi setiap elemen dari A ke B Mengkopi nilai dari satu array ke array yang lain adalah operasi umum sehingga Java memiliki subrutin untuk melakukannya.println("Anda memasukkan " + args. } Rutin main() memiliki parameter dengan tipe String[] yang merupakan array String. if (args. System.for (int i = 0. A. System. Ketika sistem memanggil rutin main(). int jumlah) di mana arraySumber dan arrayTujuan bisa berbentuk array dengan tipe apapun. Suatu tipe array. jika kelas yang memiliki rutin main() bernama programKu.length > 0) { . double[] kpi. 0. kita bisa menulis fungsi yang membuat kopi array dengan tipe double sebagai berikut : double[] kopi( double[] sumber ) { // Membuat dan mengembalikan kopi array sumber // Jika sumber null. dan "tiga". maka parameter dari baris perintahnya adalah "satu".length + " parameter dari baris perintah").length. yaitu System. // Kopi array sumber kpi = new double[sumber. Juga bisa digunakan sebagai tipe keluaran suatu fungsi.length].out. 0. misalnya double[] adalah tipe Java biasa. return kpi.arraycopy(). i < A. int indeksAwalSumber. maka kembalikan null if ( sumber == null ) return null. kpi. "dua". Jika kita menggunakan konsol. User bisa menambahkan input tambahan dalam perintah ini setelah nama program yang akan dijalankan.

Berapa orang yang Anda harus tanya untuk mendapatkan hari ulang tahun yang sama dengan orang sebelumnya? Tentunya jawabannya akan tergantung pada faktor yang bersifat acak. apakah hari ulang tahun tersebut telah digunakan? Jawabannya adalah nilai boolean true atau false. misalnya i. kita ambil contoh suatu masalah yang disebut dengan masalah ulang tahun: Misalnya ada N orang di dalam suatu ruangan. Hingga sekarang.length. kita akan mengecek terlebih dahulu apakah sudahDitanya[i] bernilai true. sudahDitanya = new boolean[365]. contoh yang telah diberikan adalah bagaimana mengolah array dengan mengakses elemennya secara berurutan (sequential access). i++) System. Ada 365 kemungkinan hari ulang tahun (Kita abaikan sementara tahun kabisat). Jika sudahDitanya[i] bernilai false.out. meskipun tahunnya berbeda)? Kebanyakan orang salah menerka jawabannya. Sekarang kita lihat dengan versi masalah yang berbeda: Misalnya kita memilih orang secara acak dan menanyakan ulang tahunnya. kita perlu tahu. dan begitu seterusnya hingga semua orang di dalam ruangan ditanyakan. Jika hari ulang tahunnya . Berapa kemungkinan dua orang di dalam ruangan tersebut memiliki ulang tahun yang sama (yang dilahirkan pada tanggal dan bulan yang sama. Jika tidak maka orang ini adalah orang kedua dengan ulang tahun yang sama. Untuk setiap kemungkinan hari ulang tahun. kita harus mencatat semua ulang tahun yang kita sudah tanyakan. Untuk menyimpan data ini. Jika tidak ada parameter dari baris perintah yang dimasukkan. yaitu setiap elemen bisa diakses kapan saja secara langsung.System. Misalnya. kemudian kita akan tanyakan lagi kepada orang lain. Artinya kita sudah selesai. Tanggal-tanggal pada satu tahun dinomori dari 0 hingga 364. akan tetapi kita bisa simulasikan dengan program komputer dan menjalankan beberapa kali hingga kita tahu berapa kira-kira orang harus dicek. for (int i = 0. Artinya elemen-elemen array diproses satu per satu dalam urutan dari awal hingga akhir. static void masalahUlangTahun() { // Melakukan simulasi dengan memilih seseorang secara acak // dan mengecek hari ulang tahunnya. kita bisa gunakan array dari 365 nilai boolean: boolean[] sudahDitanya. Untuk mensimulasikan percobaan ini. } } // akhir main() } // akhir kelas CLDemo Perhatikan bahwa parameter args tidak mungkin null meskipun tidak ada parameter yang dimasukkan. Nilai sudahDitanya[i] akan bernilai true jika orang yang kita tanya berulang tahun pada hari tersebut. Akan tetapi salah satu keuntungan array adalah bahwa array bisa digunakan untuk mengakses elemennya secara acak.println("Parameter tersebut adaah :").println(" " + args[i]). maka panjang array ini adalah nol. i < args. Kita akan ganti sudahDitanya[i] dengan true. Ketika kita memilih satu orang dan menanyakan hari ulang tahunnya. Pada awalnya semua nilai pada array sudahDitanya[i] bernilai false.out. maka belum ada orang sebelum ini yang memiliki hari ulang tahun tersebut.

// hentikan program dan laporkan berapa orang yang sudah dicek boolean[] sudahDitanya. Misalnya kita ingin membuat beberapa kolom secara paralel -. Data untuk baris ke-i bisa didapatkan dari masingmasing array ini. sudahDitanya[ultah] = true. i++) Array paralel adalah menggunakan beberapa array dengan indeks yang sama.y.random()*365). // Awalnya. } System. semua nilai adalah false hitung = 0. Tidak ada yang salah dengan cara ini. keluar // Jika tidak catat dalam array int ultah. array y di kolom kedua. akan tetapi cara ini berlawanan dengan filosofi berorientasi objek yang mengumpulkan data yang berhubungan di dalam satu objek. // Untuk mencatat ulang tahun yang sudah ditanyakan // Nilai true pada sudahDitanya[i] berarti orang lain // sudah ada yang berulang tahun pada hari i int hitung.out. // Posisi pesan . Jika kita ingin menggunakan array yang sama untuk simulasi kedua. hitung++. Jika kita mengikuti aturan seperti ini. // Ulang tahun seseorang ultah = (int)(Math.// sama dengan orang yang pernah kita tanya sebelumnya. i < 365."). dan seterusnya. Misalnya saya menulis kelas seperti class DataString { // Data dari salah satu pesan int x. kita harus mereset ulang semua elemen di dalamnya menjadi false kembali dengan perulangan for for (int i = 0.println("Ulang tahun yang sama ditemukan setelah menanyakan " + hitung + " orang. while (true) { // Ambil ulang tahun secara acak dari 0 hingga 364 // Jika ulang tahun telah ditanya sebelumnya. // Jumlah orang yang sudah pernah ditanya sudahDitanya = new boolean[365]. amaka kita tidak harus membayangkan hubungan data yang satu dan yang lainnya karena semua data akan dikelompokkan di dalam satu tempat. if ( sudahDitanya[ultah] ) break.array x di kolom pertama. } // akhir masalahUlangTahun() Subrutin ini menggunakan fakta bahwa array boolean yang baru dibuat memiliki seluruh elemen yang bernilai false. array warna di kolom ketiga.

"Desember". misalnya dengan data = new DataString[JUMLAH_PESAN]. i++) data[i] = new DataString().y. yang melambangkan bulan dalam satu tahun dari Januari hingga Desember. "November". "Maret". Misalnya kita memiliki nilai bulan dari 0 hingga 11. Terakhir berkaitan dengan pernyataan switch.x. . nilai setiap elemen array adalah null.} Color warna. Kita ingin menyimpan data di dalam objek yang bertipe DataString. case 11: bulanString = break. "September". . misalnya dengan array namaBulan yang dideklarasikan sebagai berikut : static String[] namaBulan = { "Januari". Yang kita sudah buat hanyalah kontainernya saja. "Salah bulan". case 1: bulanString = break. case 2: bulanString = break. case 3: bulanString = break. Untuk itu elemen di dalamnya bisa kita buat dengan perulangan for seperti : for (int i = 0. "Agustus". "Maret". Isi dari data bernilai null hingga kita membuat array baru. "Desember" }. kita bisa menggunakan array bertipe DataString[]. akan tetapi tidak ada objek yang dibuat. Elemen di dalamnya berupa objek yang belum pernah kita buat. "Juli". Sekarang kita bisa mengambil data setiap pesan dengan data[i]. dan data[i]. Kemudian kita bisa ganti keseluruhan switch di atas dengan bulanString = namaBulan[bulan]. "April". yang kemudian dideklarasikan sebagai variabel instansi dengan nama data sehingga DataString[] data. "Mei". "Februari". "Juni". default: bulanString = } "Januari". Kita bisa mengganti keseluruhan perintah switch tersebut dengan menggunakan array. data[i]. // Warna pesan Untuk menyimpan data dalam beberapa pesan.warna. Setelah array ini dibuat. "April". dengan perintah switch (bulan) { case 0: bulanString = break. "Februari". Kita ingin mencetaknya di layar. . "Oktober". . i < JUMLAH_PESAN.

Atau array yang berisi gambar yang ditambahkan user oleh program gambar.out. Program akan berhenti membaca input apabila input yang diterima bernilai 0 atau kurang dari nol. // Banyaknya bilangan yang sudah disimpan dalam array int bil.ambilInt()."). bahwa kita butuh sesuatu yang bisa menyimpan data di mana jumlahnya tidak tetap. jmlBilangan++. Akan tetapi program tersebut harus melacak berapa banyak bilangan yang sudah diambil dari user.println("Masukkan bilangan bulat positif (paling banyak 100 bilangan)" + ". kemudian mencetak bilangan-bilangan tersebut dalam urutan terbalik. Akan tetapi. karena semua bilangan harus disimpan pada suatu tempat. // Array untuk menyimpan nilai input dari user int jmlBilangan. masi kita buat program yang mengambil bilangan yang diinput dari user. Maka ukuran array bisa dibuat 100. (Ini adalah contoh pengolahan yang membutuhkan array. mencari jumlah atau rata-rata atau nilai maksimum beberapa bilangan. Bilangan input n tersebut kita simpa di dalam array bilangan dengan tipe int[]. bisa dilakukan tanpa menyimpan bilangan tersebut satu per satu) public class BalikBilanganInput { public static void main(String[] args) { int[] bilangan. maka variabel terpisah digunakan untuk menyimpan berapa banyak sisa tempat kosong yang masih bisa diisi di dalam array. Di sini jelas. Misalnya dalam contoh berikut : Suatu array menyimpan baris teks dalam program pengolah kata. suatu program yang membaca bilangan bulat positif dari user. Karena ukuran array tidak bisa diubah. if (bil <= 0) break. while (true) { System. Banyak lagi contoh program misalnya. Sebagai contoh sederhana. // Bilangan yang diambil dari user // Buat array dengan 100 bilangan int // Belum ada bilangan yang disimpan bilangan = new int[100]. bilangan[jmlBilangan] = bil. Bayangkan misalnya. masukkan nol untuk mengakhiri. . kemudian menyimpannya untuk diproses kemudian. jmlBilangan = 0. Kita gunakan variabel terpisah bernama jmlBilangan. bil = KonsolIO. sering kali jumlah data yang disimpan dalam array bisa berubah setiap saat.print("? ").Sangat mudah bukan? Array Dinamis Panjang suatu array tidak bisa diubah setelah dibuat. nilai jmlBilangan akan bertambah satu. Array Setengah Penuh Bayangkan suatu aplikasi di mana sejumlah item yang ingin kita simpan di dalam array akan berubah-ubah sepanjang program tersebut berjalan. Katakan banyaknya bilangan yang bisa disimpan tidak lebih dari 100 buah. Atau suatu array yang menyimpan daftar komputer yang sedang mengakses halaman suatu website. System. Setiap kali suatu bilangan disimpan di dalam array.out.

ArrayPemain[2]. maka bilangan-bilangan tersebut diisi pada array di posisi 0. dan objek pemailn akan disimpan dalam array. int jumlahPemainAktif = 0. Yang kedua adalah menentukan di mana indeks kosong berikutnya di dalam array. Untuk menghapus seorang pemain mungkin sedikit lebih sulit karena kita tidak ingin meninggalkan lubang di tengah-tengah array. mungkin kita memiliki kelas bernama Pemain sebagai lambang pemain di dalam game. Yang pertama.1 hingga 0. bisa disimpan di dalam array ArrayPemain dengan tipe Pemain[]. dan seterusnya.} System. for (int i = jmlBilangan . maka salah satu caranya adalah memindahkan posisi pemain terakhir ke posisi pemain yang meninggalkan game. Jika kita tidak peduli urutan pemainnya. tidak lagi ada di dalam array. Misalnya. 2. misalnya jumlahPemainAktif untuk mencatat banyaknya pemain yang sedang aktif berada di dalam game. secara sederhana : // Tambah pemain di tempat kosong ArrayPemain[jumlahPemainAktif] = pemainBaru.println( bilangan[i] ). Ketika kita akan mencetak angka di dalam array. // Di awal game.1]. Ingat bahwa pemain ArrayPemain[jumlahPemainAktif] tidak ada. karena nilai jumlahPemainAktif kita kurangi dengan . Pemain yang sebelumnya ada di posisi jumlahPemainAktif -1 sekarang ada di array sebanyak 2 kali. Misalkan kita ingin menulis program game. variabel jumlahPemainAktif akan lebih dari 0. Misalnya jumlah maksimum pemain di dalam game adalah 10 orang. maka kita bisa mendeklarasikan variabelnya sebagai : Pemain[] ArrayPemain = new Pemain[10].1. ArrayPemain[1]. 1. } // akhir kelas BalikBilanganInput Penting untuk diingat bahwa jmlBilangan memiliki dua peran. Prosedur untuk menambah pemain baru. di mana pemain bisa masuk ke dalam game dan keluar dari game setiap saat. Sebagai programmer berorientasi objek yang baik. maka poisisi penuh berikutnya adalah di lokasi jmlBilangan . // Hingga 10 pemain. jumlahPemainAktif++. Misalnya kita ingin menghapus pemain pada indeks k pada ArrayPemain. jika 4 bilangan sudah dimasukkan ke dalam array. Karena jumlah pemain bisa berubah-ubah maka kita bisa menggunakan variabel bantu. dan 3. adalah melacak banyaknya bilangan yang sudah dimasukkan di dalam array. Daftar pemain yang sedang ada di dalam game.println("\nBilangan yang Anda masukkan dalam urutan terbalik adalah :\n"). Mari kita lihat contoh lain yang lebih realistis. jumlahPemainAktif--. Akan tetapi sekarang ia berada di bagian yang valid. i >= 0. misalnya ArrayPemain[0]. i--) { System. sehingga perulangan for mencetak bilangan dari jmlBilangan . // And increment playerCt to count the new player.out. misalnya : ArrayPemain[k] = ArrayPemain[jumlahPemainAktif .out. Maka posisi kosong berikutnya adalah posisi 4. Pemain yang sebelumnya ada di posisi k. } } // akhir main(). tidak ada pemain yang aktif Setelah beberapa pemain masuk ke dalam game.1.

kotak bertepi bulat. dan ia memiliki kelas-kelas turunan yang merupakan bentuk-bentuk khusus.satu. // Letakkan beberapa objek di dalam array. objek tersebut bisa saja berupa kelas turunan dari Pemain. sehingga mungkin juga array tersebut menyimpan beberapa jenis Pemain misalnya pemain komputer. hanya referensinya saja yang disimpan di sana. Contoh lainnya. Objek Pemain sendiri tidak disimpan di dalam array. Untuk melakukannya. oval. // Array untuk menyimpan 100 gambar. yang semuanya adalah kelas turunan dari Pemain. } Perlu ditekankan bahwa contoh Pemain di atas memiliki tipe dasar suatu kelas. .1 akan tetap diproses seperti biasa. Elemennya bisa bernilai null atau referensi ke suatu objek yang bertipe Pemain. atau pemain lainnya. gambar[1] = new Garis(). // (Program betulan akan menggunakan beberapa gambar[2] = new OvalBerwarna(). Pemain k+ mengganti pemain k yang keluar dari game. i < jumlahPemainAktif. perhatikan contoh pernyataan berikut BentukGeometri[] gambar = new BentukGeometri[100]. dan berikutnya. // parameter di sini int jmlGambar = 3. seperti garis. Misalnya. misalnya kelas BentukGeometri menggambarkan suatu bentuk geometri yang bisa digambar pada layar. seperti didiskusikan sebelumnya). Ingat bahwa setiap elemen di dalam array harus menyimpan satu nilai. Pemain k+2 mengganti pemain yang pindah sebelumnya. dan sebagainya. // Lacak jumlah objek di dalam array bisa diilustrasikan sebagai berikut. kotak. semua pemain di posisi k+1 ke atas harus dipindahkan satu posisi ke bawah. pemain manusia. Kodenya bisa dibuat seperti for (int i = k+1. atau oval berisi warna. (BentukGeometri sendiri bisa berbentuk kelas abstrak. Misalnya kita ingin menghapus pemain di posisi k. Karena aturan pemberian nilai pada Java. gambar[0] = new Kotak(). akan tetapi satusatunya nilai dari posisi 0 hingga jumlahPemainAktif . akan tetapi kita ingin agar urutan pemain tetap sama. Kemudian array bertipe BentukGeometri[] bisa menyimpan referensi objek yang bertipe kelas turunan dari BentukGeometri. i++) { ArrayPemain[i-1] = ArrayPemain[i].

maka semua grafik dalam array bisa digambar dengan perulangan sederhana for (int i = 0. Pernyataan "gambar[i]. Setiap objek tahu bagaimana menggambar dirinya sendiri. Jika BentukGeometri memiliki metode "void gambarUlang(Graphics g)" untuk menggambar pada grafik g.Array tersebut bisa digunakan dalam program gambar.gambarUlang(g). Array bisa digunakan untuk menampung gambar-gambar yang akan ditampilkan. Ini adalah contoh dari polimorfisme dan pengolahan array. sehingga perintah dalam perulangan tersebut sebetulnya melakukan tugas yang berbeda-beda tergantung pada objeknya." memanggil metode gambarUlang() yang dimiliki oleh masing-masing gambar pada indeks i di array tersebut. . i < jmlGambar.gambarUlang(g). i++) gambar[i].

// Ubah referensi ArrayPemain ke array baru. Kita tidak bisa membuat array tersebut lebih besar. 0. kemudian mengubah isi variabel array tersebut ke array baru itu. // Array baru System. Tentu saja. Karena ukuran array tidak bisa berubah. yaitu 100 int.length). kita akan membuat array baru yang lebih besar. Ingat bahwa setelah ini dilakukan. dan 100 BentukGeometris. cara yang lebih baik adalah apabila kita bisa mengubah ukuran array sesuka kita kapan saja. Variabel ArrayPemain akan merujuk pada array baru. meskipun array sudah penuh if (jumlahPemainAktif == ArrayPemain. Ingat bahwa sebenarnya variabel array tidak menyimpan array yang sesungguhnya.. akan lebih indah jika kita membuat kelas untuk menangani hal ini..length) { // Array sudah penuh. } // Di sini kita sudah tahu bahwa pasti ada tempat di array baru. di mana ArrayPemain adalah array dengan tipe Pemain[] dan jumlahPemainAktif[/code] adalah jumlah pemain yang sudah digunakan array tersebut. Mari kita lihat kembali contoh game di atas. dan tambah satu jumlahPemainAktif nya Jika kita akan melakukan hal ini terus menerus. 100 Pemain. Variabel ini hanya menyimpan referensi ke objek tersebut. akan tetapi kita bisa membuat array baru yang lebih besar. array tersebut hanya bisa menampung maksimum sebanyak elemen yang didefinisikan pada pembuatan array. ArrayPemain[jumlahPemainAktif] = pemainBaru. karena ia tidak lagi digunakan. // Ukuran array baru Pemain[] temp = new Pemain[ukuranBaru]. Jika pemain baru masuk dan array tersebut sudah penuh. Array dinamis memiliki jenis operasi yang sama dengan array : mengisi nilai pada posisi tertentu dan mengambil nilai di posisi tertentu.length. int ukuranBaru = 2 * ArrayPemain. ada batas tententu dalam jumlah elemennya. Objek mirip array yang bisa berubah ukuran untuk mengakomodasi jumlah data yang bisa ia tampung disebut array dinamis. Array lama akan diambil oleh pemulung memori. // kemudian kopi isi array lama ke array baru lalu ubah // ArrayPemain ke array baru. ArrayPemain = temp. bukan 101? Alternatif yang umum adalah membuat array yang sangat besar sehingga bisa digunakan untuk dalam kehidupan sehari-hari. Dalam banyak kasus. Buat array baru yang lebih besar. akan tetapi nilai ArrayPemain[0] sama dengan sebelumnya. jumlahPemainAktif++.arraycopy(ArrayPemain. temp.. 0. // .Array Dinamis Dalam contoh-contoh di atas. ArrayPemain. Akan tetapi cara ini tidak baik. Misalnya kita tidak ingin membuat limit banyaknya pemainnya yang bisa ikut main. karena akan sangat banyak memori komputer yang terbuang karena tidak digunakan. Memori itu mungkin lebih baik digunakan untuk yang lain. // Tambah pemain baru. Apalagi jika komputer yang akan digunakan tidak memiliki memori yang cukup untuk menjalankan program tersebut. Berikut ini adalah kode untuk melakukan hal di atas: // Tambah pemain baru. Akan tetapi tidak ada batas maksimum dari jumlah array (hanya tergantung pada jumlah memori . Tentunya kita harus mengkopi semua isi di array yang lama ke array baru. adanya batas maksimum tersebut tidak diinginkan. ArrayPemain[0] akan menunjuk pada lokasi memori yang berbeda.. Kenapa harus bekerja dengan hanya 100 bilangan bulat saja.

length) { // Posisi yang ditentukan berada di luar array data // Besarkan ukuran array 2x lipat. akan tetapi arraynya akan dibuang dan diganti dengan array baru yang lebih besar apabila diperlukan. Kita bisa menulis ulang program tersebut dengan menggunakan ArrayDinamisInt. maka perintah bilangan. int nilai) { // Simpan nilai ke posisi yang ditentukan di dalam array // Data array tersebut akan bertambah besar jika diperlukan if (posisi >= data.length) return 0. Fungsi bilangan. Pada contoh pertama. adalah kelas yang mengimplementasikan array dinamis int : public class ArrayDinamisInt { private int[] data.komputer yang tersedia). Karena semua posisi di dalam array adalah nol. data. // Array akan bertambah besar jika diperlukan } public // // // if int get(int posisi) { Ambil nilai dari posisi tertentu di dalam array.put(pos.arraycopy(data. Jika bilangan adalah variable bertipe ArrayDinamisInt. } public void put(int posisi. Di sini misalnya. Perintah . } data[posisi] = nilai. Dalam kelas array dinamis.nilai) akan menyimpan bilangan pada posisi pos di array dinamis tersebut.println("Ukuran array dinamis diperbesar menjadi " + ukuranBaru). int[] dataBaru = new int[ukuranBaru]. 0. dataBaru. else return data[posisi]. kita menggunakan array untuk menyimpan bilangan bulat positif yang dimasukkan oleh user. 0. // Array untuk menyimpan data public DynamicArrayOfInt() { // Konstruktor. // Perintah berikut hanya untuk demonstrasi System.get(pos) mengambil nilai yang disimpan pada posisi pos.get[i]. System. Referensi ke bilangan[i] diganti dengan bilangan. if (posisi >= ukuranBaru) ukuranBaru = 2 * posisi. metode put dan get akan diimplementasikan sebagai metode instansi. buat ukurannya sebesar 2*posisi int ukuranBaru = 2 * data.out.length).length. data = dataBaru. maka jika posisi tertentu di luar data array. Atau jika ukurannya masih // terlalu kecil. } } // akhir kelas ArrayDinamisInt Data pada objek ArrayDinamisInt disimpan dalam array biasa. data = new int[1]. nilai 0 akan dikembalikan (posisi >= data.

1. hanya kelas-kelasnya saja yang berlainan.out. Kelas tersebut mungkin bernama ArrayDinamisBentukGeometri. } // akhir kelas BalikBilanganInput ArrayLists dan Vector ArrayList Kelas ArrayDinamisInt bisa digunakan jika kita membutuhkan array dengan batas maksimum yang tak terbatas. i >= 0. int bil."bilangan[jmlBilangan] = bil."). Hal ini disebut dengan pemrograman generik. int jmlBilangan. if (bil <= 0) break.put(jmlBilangan.println( bilangan. ArrayDinamisPemain.ambilInt(). jmlBilangan++. } } // akhir main(). dan sebagainya. Juga demikian jika kita ingin membuat kelas ArrayDinamisDouble. // Belum ada bilangan yang disimpan System. masukkan nol untuk mengakhiri. dan akan tampak sama persis dengan ArrayDinamisInt dengan beberapa perubahan di mana "int" muncul akan diganti dengan "BentukGeometri". bil = KonsolIO. Yang agak sedikit lucu adalah kelas tersebut sangat mirip isinya.out. Beberapa bahasa pemrograman seperti C++ memiliki fasilitas untuk melakukan pemrograman generik. kita harus membuat kelas baru.".out.out.put(jmlBilangan. Berikut ini adalah programnya: public class BalikBilanganInput { public static void main(String[] args) { user array ArrayDinamisInt bilangan. bilangan. } System. Java tidak memiliki fasilitas seperti itu (maksudnya tidak sama persis). i--) { System. .bil). for (int i = jmlBilangan .println("\nBilangan yang Anda masukkan dalam urutan terbalik adalah :\n"). while (true) { System.bil).print("? "). Akan tetapi jika kita ingin menyimpan BentukGeometri misalnya.get(i) ). Akan sangat lebih baik apabila kita bisa membuat kelas umum yang berlaku untuk semua kelas.println("Masukkan bilangan bulat positif." kita ganti dengan "bilangan. // Array untuk menyimpan nilai input dari // Banyaknya bilangan yang sudah disimpan dalam // Bilangan yang diambil dari user bilangan = new ArrayDinamisInt(). jmlBilangan = 0. Tapi kita bisa membuat sesuatu yang mirip dengan itu pada Java dengan menggunakan struktur data yang memiliki tipe "Object".

Jika kita buat kelas ArrayDinamisObject. maka objek tersebut akan dibuang. pesan kesalahan akan ditampilkan.remove(obj) -. maka objek apapun bisa diberikan kepada subrutin tersebut. Kemudian ukuran ArrayList berkurang 1. dan kita tidak boleh mengambil posisi di luar ukuran ArrayList.Fungsi ini menghasilkan ukuran ArrayList saat ini. dan mengganti apapun yang sudah disimpan sebelumnya pada posisi N.ArrayList.Jika objek tersebut ada di dalam ArrayList. .set(N. objek ArrayList selalu memiliki ukuran tertentu. Elemen lain setelah posisi objek tersebut di dalam ArrayList akan digeser satu posisi.1.size() -.1. Dalam hal ini. Misalnya daftar adalah variabel dengan tipe ArrayList. obj) -.add(obj) -." di awal program kita. Parameter obj merujuk pada objek dengan tipe apapun.util.Pada Java.get(N) -.size() . Kemudian ukuran ArrayList akan berkurang 1.size() . N harus berada pada rentang 0 hingga daftar. Sebenarnya.Untuk bilangan bulat N. Elemen setelah ini akan digeser satu posisi.size() . maka kita bisa menyimpan objek apapun. • daftar. ukuran ArrayList bisa bertambah kapan saja jika diperlukan.get(N) = 5 tidak boleh dilakukan) • daftar.util. kita harus memberikan "import java. Akan tetapi. Posisi valid dalam daftar adalah yang bernomor 0 hingga daftar.Mengambil nilai yang disimpan pada posisi N pada ArrayList. N harus bertipe bilangan bulat antara 0 hingga daftar. karena Java telah memiliki kelas standar yang dinamakan ArrayList yang sifatnya mirip dengan yang kita sebutkan sebelumnya.get(N) pada ekspresi di sebelah kiri daftar.util. atau bisa bernilai null.remove(N) -. Kita akan jelaskan sebagian yang sangat berguna. Kelas ArrayList berbeda dengan kelas ArrayDinamisInt dalam arti. Ini sebenarnya bukan programming generik sebenarnya. maka perintah ini akan menghapus posisi ke-N pada ArrayList. Artinya setiap objek dapat dirujuk oleh variabel bertiipe Object. ArrayList mirip seperti array biasa. • daftar. ArrayList disimpan dalam paket java.1. Bilangan bulat N harus berada pada rentang 0 hingga daftar. jadi jika kita ingin menggunakan kelas ArrayList dalam sebuat program. Jika suatu subrutin memiliki parameter formal bertipe Object. Jika N berada di luar rentang ini. kemudian menambah ukurannya dengan 1. Semua objek dapat dimasukkan dalam array bertipe Object[]. setiap kelas adalah kelas turunan dari kelas yang bernama Object.*. dan tidak berlaku untuk tipe primitif seperti int dan double. kita tidak perlu membuat kelas ArrayDinamisObject sendiri. • daftar. hanya yang pertama saja yang dibuang. Jika obj terdapat dalam ArrayList lebih dari satu kali." atau "import java. • daftar.1. Panggilan konstruktor new ArrayList() akan membuat ArrayList dengan ukuran nol. Perintah ini mirip dengan perintah A[N] = obj pada array A. • daftar. Ingat bahwa ukurannya bisa nol. Kelas ArrayList memiliki banyak metode instansi.Mengisi suatu objek obj di posisi N dari suatu ArrayList.size() . Akan tetapi kita tidak bisa menggunakan daftar. Memanggil fungsi ini mirip dengan memanggil array seperti A[N] untuk suatu array A.Menambah objek di akhir ArrayList.

2. sebagai salah satu kumpulan kelas yang digunakan untuk bekerja dengan sekumpulan koleksi objek.Fungsi untuk mencari suatu objek obj di dalam ArrayList.get(i)" diperlukan karena aturan dalam Java sehingga perintah dalam kurung akan dijalankan terlebih dahulu sebelum metode jalan() dipanggil. maka kita perlu menggunakan casting tipe untuk mengubahnya menjadi tipe Player.get(i). Variabel ini dideklarasikan seperti : • daftar. maka kita hanya perlu memberikan perintah paraPemain. yaitu dengan for (int i = 0. Kita masih bisa melihat Vector digunakan pada program lama. Supaya kita bisa menggunakan hasil keluarannya. Dalam hal ini objek yang diambil oleh fungsi ini sebenarnya bertipe Pemain. maka kita bisa menuliskan kode untuk memberi giliran kepada semua pemain untuk jalan. akan tetapi memiliki kelas yang sangat mirip yaitu java. Jika pemainBaru adalah variabel yang bertipe Pemain.jalan(). maka fungsi ini akan mengembalikan -1. Satu-satunya kesulitan yang akan kita temui adalah ketika kita ingin mengambil nilai yang disimpan pada posisi i di dalam ArrayList. Pemain yang berada dalam game disimpan dalam ArrayList bernama paraPemain. dan kita inisialisasikan dengan objek kosong dengan perintah paraPemain = new ArrayList(). i++) { Pemain pmn = (Pemain)paraPemain. kemudian memanggil metode jalan() pada pemain yang baru diambil tersebut. Jika tidak.util. Versi awal Java tidak memiliki ArrayList.kita akan membuat pemain dalam game yang digambarkan dengan objek dengan tipe Pemain. Tanda kurung di sekitar "(Pemain)paraPemain. maka pemain baru tersebut bisa ditambahkan ke dalam ArrayList dan ke dalam game dengan perintah : paraPemain.add(pemainBaru). maka posisinya di dalam ArrayList akan dikembalikan. Tipe keluaran fungsi ini adalah Object. . pmn.size(). dan dalam beberapa kelas standar Java. Misalnya. i < paraPemain.remove(pemain).-. Semuanya terlihat sangat mudah. Jika objek ditemukan. dan jika pemain nomor i keluar dari game. dengan cara : Pemain pmn = (Pemain)paraPemain. Vector Kelas ArrayList diperkenalkan pada Java versi 1. maka kita bisa menggunakan perintah paraPemain. sehingga kita perlu tahu tentang kelas ini. Misalnya.get(i). Atau jika pemain adalah objek bertipe Pemain yang akan kita keluarkan dari game.Vector.indexOf(obj) ArrayList paraPemain. Jika akan bahas lebih lanjut tentang "kelas koleksi" pada bagian berikutnya.jalan(). jika kelas Pemain memiliki metode instansi yang dinamakan jalan() yang dipanggil ketika seorang pemain menjalankan dadu atau kartu. Perintah ini akan mengambil elemen pada ArrayList mengcasting tipenya.remove(i).get(i)). } Dua baris di dalam perulangan for tersebut dapat digabungkan dengan satu perintah : ((Pemain)paraPemain.

Kelas ArrayList tidak memiliki metode seperti ini. Seperti ArrayList. maka tempat kosong akan diisi dengan null. Pembahasan kita akan lebih dikhususkan pada array 2 dimensi.addElement(obj) akan menambahkan Object obj di akhir vektor. Perbedaannya adalah nama metode yang berbeda untuk melakukan tugas yang sama. Array tersebut disebut array 2 dimensi. Terutama.1. Maka : • vec.size() adalah fungsi untuk mengembalikan jumlah elemen di dalam vektor. dan seterusnya." akan membuat objek array 2 dimensi dan mengisi A ke objek yang baru dibuat tersebut. Misalnya vec adalah suatu Vector. • vec. kita bisa membuat array yang bertipe array. N harus berada pada rentang 0 hingga vec. Tipe TipeDasar[][] biasanya dibaca "array 2 dimensi bertipe TipeDasar" atau "array dari array TipeDasar". seperti pada ilustrasi berikut ini : . seperti "int[][] A = new int[3][4]. akan tetapi bukan sesuatu yang biasa dilakukan untuk membuat array lebih dari 3 dimensi. • vec. deklarasi dan pemberian nilai bisa digabung menjadi satu pernyataan. Istilah "int[3][4]" bisa disebut sebagai matriks dengan 3 baris dan 4 kolom. akan tetapi ini adalah metode yang sering digunakan. karena array adalah tipe Java kelas satu.removeElement(obj) menghapus obj dari dalam vektor. maka elemen lainnya akan dihapus. array Object dan seterusnya.". Bagian int[3][4] menyatakan bahwa ada 3 array int di dalam array A. Deklarasi pernyataan "int[][] A. Hanya objek pertama yang ditemui akan dihapus. yang merupakan array 3 dimensi. Variabel ini berisi objek yang bertipe int[][]. suatu Vector mirip dengan array Object yang bisa berkembang jika diperlukan. yaitu "array bertipe array int". array String.Menggunakan Vector mirip dengan menggunakan ArrayList. Pernyataan pemberian nilai "A = new int[3] [4]. dan di setiap array int tersebut terdapat 4 int.setSize(N) akan mengubah ukuran vektor menjadi N. juga otomatis memiliki array bertipe int[][]. Jika lebih sedikit.removeElementAt(N) menghapus elemen ke-N. kita juag bisa membuat arraynya dengan tipe int[][][]. Misalnya suatu array bertipe int[]. Jika di dalam vektor terdapat elemen yang jumlahnya lebih banyak dari N. Konstruktor new Vector() membuat vektor tanpa elemen. Objek yang baru dibuat adalah objek yang merupakan array dari array int. Sama dengan remove(obj) pada kelas ArrayList • vec. Kita bisa membuat array int. Kelas Vector memiiki banyak metode lagi.size() . Sama dengan remove(N) pada ArrayList • vec. akan tetapi akan lebih mudah apabila kita bayangkan array tersebut seperti matriks. dengan tipe int[][]. Sama dengan metode add() pada ArrayList. Tidak ada batasan berapa dimensi array yang kita buat. kalau ada. atau nama metode yang berbeda untuk melakukan tugas yang sama. Seperti biasa. Cara seperti itu mungkin sedikit membingungkan. Tentunya. Array Multi Dimensi Tipe apapun bisa digunakan sebagai tipe dasar suatu array." adalah membuat variabel bernama A dengan tipe int[][].

atau . Jadi pada contoh di atas. Untuk mendapatkan jumlah kolom pada A. Jumlah kolom ini bisa didapatkan dengan menggunakan A[0]. kita harus mencari jumlah int dalam setiap baris. A[1]. A[i] [j] adalah posisi pada baris i dan kolom j. Kadang-kadang kita juga harus ingat bahwa setiap baris sebenarnya juga merupakan suatu array. Array-array ini bisa dirujuk dengan A[0]. Perlu juga diketahui bahwa A. yaitu yang disimpan pada A[0].Untuk banyak hal.length akan memberikan jumlah baris pada A. Misalnya A[1][3] adalah elemen nomor 3 pada baris 1. Setiap baris bertipe int[]. dan membayangkan bentuk matriks seperti di atas. kita bisa menambah indeks lain untuk merujuk pada posisi pada baris tersebut. A[1][3] bernilai 5. Pernyataan A[1] merujuk pada salah satu baris pada array A. kita bisa mengabaikan kenyataan di atas. Karena A[1] itu sendiri sebenarnya adalah array int. dan A[2]. Lebih umum lagi. Seperti biasa. Kita bisa mengisi nilainya atau menggunakannya seperti variabel bertipe int biasa.length. ingat bahwa posisi baris dan kolom dimulai dari 0. Seluruh elemen pada A bisa dinamakan seperti berikut : A[0][0] A[1][0] A[2][0] A[i][j] A[0][1] A[1][1] A[2][1] A[0][2] A[1][2] A[2][2] A[0][3] A[1][3] A[2][3] adalah variabel bertipe int.

Misalnya. Misalnya. maka kita akan selalu mendapatkan array dengan panjang array yang sama. array A pada gambar di atas dapat dibuat dengan perintah : int[][] A = { { 1. { -5. Jika array A dideklarasikan seperti int[][] A = new int[3][4]. A[0][2] = 0. . Jika tidak ada inisialisasi yang diberikan untuk suatu array. kolom++) { A[baris][kolom] = 0. -1 }.) Array 3 dimensi juga dibuat dan diolah dengan cara yang sama. for (int i = 0. array 3 dimensi bertipe int bisa dibuat dengan pernyataan "int[][][] B = new int [7][5][11]. maka kita bisa mengisi 0 untuk semua elemen pada A dengan menggunakan for (int baris = 0. Kita juga bisa mengilustrasikannya sebagai kubus 3-dimensi. 2. A[0][1] = 0. Masing-masing bloknya bertipe int yang bisa dipanggil dalam bentuk B[i][j][k]. Kemudian perulangan for bagian luar akan mengisi baris kedua. maka nilainya akan diisi dengan nilai awal tergantung pada tipenya : nol untuk bilangan. 12. array 2 dimensi juga sering diolah dengan menggunakan perulangan for. baris++) { for (int kolom = 0. kita bisa menjumlah semua elemen pada A dengan int jml = 0. 2. yaitu A[0][0] = 0. } } Pertama kali perulangan for bagian luar akan memproses dengan baris = 0. j < 4. { 7. dan sebenarnya pada beberapa aplikasi. Akan tetapi apabila kita membuat array dengan perintah seperti di atas. A[1]. -2.". UNtuk mengolah semua elemen pada array 2 dimensi. dan seterusnya. (Tidak ada aturan baku yang menyatakan bahwa pada setiap baris suatu array harus memiliki panjang yang sama. tentunya kita harus menggunakan perulangan for bertingkat 3. masing-masing untuk setiap barisnya.length Kita bisa mengisi array multi dimensi sekaligus pada saat dideklarasikan. dan A[0][3] = 0. Ingat sebelumnya bagaimana array 1 dimensi biasa dideklarasikan. 9 } }. false untuk boolean dan null untuk objek. kita bisa menggunakan pernyataan for bertingkat. Array dimensi lain yang lebih tinggi juga mengikuti pola yang sama. Seperti halnya array 1 dimensi. dan diletakkan di dalam tanda kurung kurawal { dan }. Dan juga. Inisialisasi array bisa juga digunakan untuk array multi dimensi. 0. kolom < 4. akan tetapi akan sangat sulit untuk membuat visualisasi struktur arraynya. yang terdiri dari beberapa inisialisasi array 1 dimensi. -3. yaitu seperti daftar nilai-nilainya yang dipisahkan dengan koma. baris < 3. i++) for (int j = 0. 5 }. i++) jml = jml + A[i][j]. Bagian dalamnya akan mengisi keempat kolom pada baris pertama. dan bagaimana isinya diinisialisasikan.atau A[2]. i < 3. juga digunakan array dengan panjang yang berbeda-beda pada setiap barisnya.length. Untuk mengolah array 3 dimensi.

Anggap array untung telah diisi dengan data. bulan++) { // hitung total keuntungan semua toko bulan ini untungBulanan[bulan] = 0. Jika suatu kelas dinamakan PapanCatur untuk merepresentasikan papan catur. Kita perlu mencatat hasil perhitungannya untuk mencari mana toko dengan keuntungan terbesar. maka kita bisa deklarasikan dengan perintah PapanCatur[][] papan = new PapanCatur[8][8]. Dalam istilah array. double untungMaks. Misalnya perusahaan yang memiliki 25 toko. yaitu bulan nomor 11. misalnya kita ingin tahu toko mana yang menghasilkan keuntungan terbesar sepanjang tahun. untung[noToko][noBulan] adalah keuntungan toko noToko pada bulan noBulan. // Total keuntungan perusahaan tahun 2009 totalUntung = 0. bulan < 12. Misalnya papan catur terdiri dari 8 baris dan 8 kolom. maka kita bisa gunakan perulangan : double untungDesember = 0. bulan < 12. ini berarti kita ingin mengetahui jumlah setiap baris pada array. toko < 25. Misalnya. dan 12 bulan dari Januari 09 hingga Desember 09 dinomori 0 hingga 11. Data ini bisa diolah lebih lanjut. bulan++) totalUntung += untung[toko][bulan].0. toko++) { untungBulanan[bulan] += profit[toko][bulan]. kita ingin menghitung keuntungan total perusahaan pada bulan Desember. Atau secara umum. kita harus menjumlahkan keuntungan setiap toko sepanjang tahun. } Kadang-kadang kita juga perlu menghitung hanya satu baris atau satu kolom saja. for (int toko = 0. Anggap masing-masing toko memiliki keuntungan yang didapat pada masing-masing toko tersebut setiap bulan pada tahun 2009. // Keuntungan terbesar suatu toko . untung[3][2] adalah keuntungan yang dibuat oleh toko nomor 3 di bulan Maret. for (int bulan = 0. total keuntungan seluruh perusahaan -.sepanjang tahun dari seluruh toko -. Misalnya. Dalam contoh ini array 1 dimensi untung[noToko] memiliki arti : Data keuntungan satu toko selama satu tahun.Suatu array 2 dimensi bisa digunakan untuk menyimpan data yang secara alami memang tersusun sebagai baris dan kolom. for (int toko = 0. for (noToko = 0. bukan keseluruhan array. Sekarang mari kita buat array 1 dimensi yang berisi total keuntungan seluruh toko setiap bulan : double[] untungBulanan. noToko++) untungDesember += untung[noToko][11]. noToko < 25. maka data keuntungan dapat disimpan dalam array untung yang dideklarasikan seperti : double[][] untung = new double[25][12].dapat dihitung dengan menjumlahkan semua elemen pada array : double totalUntung. } } Sebagai contoh terakhir untuk mengolah array keuntungan.0. toko < 25. Kadang-kadang array 2 dimensi juga digunakan untuk masalah yang tidak terlalu jelas matriksnya. Untuk menghitungnya. Jika toko-toko tersebut memiliki nomor 0 hingga 24. // Keuntungan setiap bulan untungBulanan = new double[12]. toko++) { for (int bulan = 0.

// adalah toko paling menguntungkan // // // // Sekarang kita lihat seluruh toko. dengan cara yang teoretis. Misalnya mengurutkan elemen pada array di mana nama diurutkan secara abjad. bulan++) total += untung[toko][bulan]. untungMaks adalah keuntungan terbesar dari 25 toko dan tokoTerbaik adalah toko dengan keuntung tersebut (Mungkin juga ada toko yang menghasilkan keuntungan yang persis sama.int tokoTerbaik. dan setiap elemen di dalam array adalah objek yang berisi nama dalam alamat email. // Total keuntungan suatu toko // Pertama-tama hitung keuntungan dari toko nomo 0 for (int bulan = 0. di mana kita ingin mencari objek di dalam array yang berisi suatu nama. Misalnya. Mungkin juga kita ingin mengurut array tersebut tergantung pada kriteria tertentu. for (bulan = 0. Pencarian dan pengurutan sering didiskusikan. Kita mungkin akan mencari alamat email seseorang apabila namanya diketahui. bulan++) total += untung[0][bulan]. array bisa jadi suatu mailing list. // keuntungan terbesar saat ini tokoTerbaik = toko.0. dan setiap kali kita melihat toko dengan keuntungan lebih besar dari untungMaks. Pencarian di sini berarti mencari item di dalam array yang memenuhi kriteria tertentu. bulan < 12. tipe data yang lebih kompleks biasanya digunakan. // datang dari toko ini } } // akhir for // // // // Di sini. Contoh lainnya adalah mengurutkan elemen pada array berdasarkan kode pos. . Ini adalah contoh pencarian. dengan menggunakan contoh array bilangan. toko++) { // Hitung keuntungan toko tersebut sepanjang tahun total = 0. kita ganti untungMaks dan tokoTerbaik dengan toko tersebut for (toko = 1. tokoTerbaik = 0. // Nomor toko yang memiliki keuntungan terbesar double total = 0. // Mulai dengan anggapan toko nomor 0 untungMaks = total. bulan < 12. Pengurutan dan Rekursi Dua jenis teknik pemrosesan array yang paling umum adalah pencarian dan pengurutan. // Bandingkan keuntungan toko ini dengan untungMaks if (total > untungMaks) { untungMaks = total.) Pencarian. toko < 25.0. Pengurutan berarti menata ulang semua item di dalam array dalam urutan tertentu (urutan naik atau turun tergantung konteksnya). Dalam situasi sebenarnya.

yang sesungguhnya adalah koleksi data yang besar dan terorganisir. masing-masing record berisi nama dan alamat email. dan cek apakah isinya sama dengan item yang kita cari. Misalnya array yang kita cari bertipe int[]. Dalam contoh mailing list di atas. maka pencarian selesai. Dalam bagian ini. Lebih jauh. yang artinya integer tersebut tidak ditemukan. Field dari record tersebut mungkin nama depan. nama akhir. Berikut ini adalah metode untuk mencari integer tertentu dalam array. kita akan melihat tentang rekursi dan aplikasinya. maka kita yakin bahwa item yang kita cari tidak ada dalam array. Kita akan menyebut masing-masing objek di dalam array sebagai record. Jika ketemu. static int cari(int[] A. Jika N ada dalam array . contoh-contoh yang disediakan akan mengikuti tradisi menggunakan array bilangan. alamat email. Jika integer tersebut tidak ada dalam array. Subrutin untuk mengimplementasikan algoritma tersebut mudah kita tulis. dan kita ingin melakukan pencarian atau pengurutan array berdasarkan nilai salah satu variabel instansi pada array tersebut. Jika kita sudah melihat semua item dan tidak ada item yang sama. dan seterusnya. Pengurutan berarti melakukan penataan elemen di dalam array sehingga field kunci record akan terurut berdasarkan urutan naik atau turun. • • • • • Pencarian List Asosiasi Pengurutan Rekursi Pengurutan Cepat Pencarian Ada algoritma sederhana yang bisa digunakan untuk mencari suatu item pada array : Lihat setiap array. Suatu rubrutin disebut rekursif jika ia memanggil dirinya sendiri baik secara langung atau tak langsung. Dalam konteks pencarian dan pengurutan. Rekursi dapat digunakan untuk menyelesaikan masalah kompleks dengan menguranginya menjadi masalah yang lebih sederhana.Contoh-contoh ini bisa dibuat lebih umum yaitu kita mempunyai array yang berisi objek. Kita bisa gunakan beberapa istilah yang bersumber pada "database". Jika integer ditemukan. maka metode ini akan mengembalikan indeks dalam array di mana item tersebut ditemukan. salah satu field diambil sebagai field kunci. Mencarian berarti mencari suatu record di dalam array yang memiliki nilai tertentu pada field kuncinya. Variabel instansi di dalam objek disebut field dari record tersebut. int N) { // Mencari integer N di dalam array A // Kondisi akhir : jika N tidak ada dalam array // maka kembalikan -1. maka metode tersebut akan mengembalikan nilai -1. Kita akan contoh beberapa record dan kunci untuk mengingatkan kita pada aplikasi yang lebih praktis.

maka kita bisa menghapus setengah dari keseluruhan elemen hanya dengan melihat satu nilai. . Akan tetapi jika kita tahu bahwa elemen di dalam array diurut dalam urutan menaik atau urutan menurun. yaitu indeks di mana A[i] == N for (int indeks = 0. Maka elemen tersebut pasti ada di lokasi tertentu sebelum posisi ke-500. Karena 42 kurang dari 93. Cara berikutnya adalah melihat di lokasi 250. } // Jika kita sampai di sini. berarti N belum ditemukan // Kembalikan -1. return -1. akan tetapi ide dasarnya sangat mudah : Jika kita mencari suatu item dalam suatu array yang terurut. Tentu saja. maka tidak ada lagi algoritma alternatif yang lebih baik dari ini. maka kita bisa menghilangkan lokasi 0 hingga 250 dan memfokuskan pencarian antara 251 dan 499. dan karena elemen di dalam array tersebut dalam urutan menaik. Kemudian kita cek item ke-500 dalam array. hanya ada satu lokasi yang akan kita cek. Jika kita tidak mengetahui apa-apa tentang isi dan urutan item pada array. Jika misanya lokasi tersebut berisi 21. waktu yang dibutuhkan untuk mengurutkan array tidak sebentar.// kembalikan i. Setelah kira-kira 10 langkah pengujian. // N ditemukan pada indeks ini. indeks < A. Yang berikutnya adalah kira-kira di lokasi ke-125 setelah itu. kita bisa simpulkan bahwa 42 tidak mungkin ada di item ke-501 ke atas. maka waktu pengurutan array akan terbayarkan dengan cepat. Meskipun implementasinya tidak mudah. } Metode seperti ini dimana pencarian dilakukan dengan menguji setiap item disebut pencarian linier (linear search). indeks++) { if ( A[indeks] == N ) return indeks. yang berikutnya adalah sekitar 62 lokasi setelah itu.length. Pencarian biner (binary search) adalah metode untuk mencari suatu item dalam array yang sudah diurutkan. maka kita bisa menggunakan algoritma lain yang lebih cepat. dan ternyata isinya adalah 93. Misalnya kita ingin mencari bilangan 42 dalam array yang sudah diurutkan yang terdiri dari 1000 bilangan bulat. Anggap bahwa array tersebut diurutkan dalam urutan menaik (dari kecil ke besar). akan tetapi jika array ini akan dicari berulang kali.

Jika nilai di tengah-tengah tersebut persisi sama denan N. maka kembalikan // nilai i. (Secara matematika. Berikut ini adalah subrutin yang mengembalikan lokasi di mana N berada di dalam array terurut A. maka rentang bawahnya bisa dibuang. maka nilai -1 akan dikembalikan. Jika tidak kembalikan -1 int lokasiTerkecil = 0. jumlah langkah yang diperlukan adalah logaritmik dari jumlah item di dalam array). maka kita hanya perlu mencari 20 kali. kita bisa mengurangi kemungkinan dan mengurangi rentang pencarian.1.length . kita hanya perlu mencatat rentang lokasi di mana kira-kira N bisa ditemukan. maka pencarian selesai.Cara ini akan jauh lebih mudah dan lebih cepat daripada harus mencari semua elemen di dalam array.1. int lokasiTerbesar = A. Jika kurang dari N. maka rentang bagian atasnya bisa dibuang. if (A[tengah] == N) { // N ditemukan di sini return tengah. Operasi dasarnya adalah mencari item di tengah-tengah rentang tersebut. Jika item ini lebih besar dari N. di mana A[i] == N. Jika ada satu juta elemen di dalam array. static int pencarianBiner(int[] A. int N) { // Mencari bilangan N pada array A // Kondisi awal : A harus diurut menaik (dari kecil ke besar) // Kondisi akhir : Jika N ada dalam array. Jika ukurang pencarian berkurang menjadi nol. while (lokasiTerbesar >= lokasiTerkecil) { int tengah = (lokasiTerkecil + lokasiTerbesar) / 2. maka nilai N tidak ada dalam array. } else if (A[tengah] > N) { // buang lokasi >= tengah lokasiTerbesar = tengah . Jika N tidak ditemukan. . Untuk membuat subrutin pencarian biner pada Java yang mencari item N pada array A. Pada setiap langkah.

kita menganggap bahwa tidak ada dua pasangan dalam list yang memiliki kunci yang sama. // Kembalikan -1. suatu kompiler harus melacak di mana lokasi suatu variabel pada memori. Contoh lainnya adalah mailing list. Item di dalam list tersebut mungkin berupa objek dari kelas : class EntriTelepon { String nama. Dengan kata tertentu. Kompiler dapat menggunakan list asosiasi di mana kuncinya adalah nama variabel dan nilainya adalah alamat variabel tersebut di memori. yang menghubungkan nama dan alamat email dalam daftar tersebut. yang artinya item tidak ditemukan return -1. String noTelp. lokasiTerbesar < lokasiTerkecil // yang berarti nilai N tidak ada dalam array. kita bisa menggunakan kamus untuk mencari definisinya. cari nilai n yang berhubungan dengan k. Kamus menghubungan kata dengan definisi. Operasi dasar dari list asosiasi adalah sebagai berikut : Dengan kunci k. Misalnya. Secara umum.} else { // buang lokasi <= tengah lokasiTerkecil = tengah + 1. Kita bisa membayangkan kamus sebagai daftar suatu pasangan (pair) dalam bentuk (k. Contoh lain yang mungkin berhubungan adalah direktori telepon yang menghubungkan nama dan nomor telepon. Contoh umum dari suatu list asosiasi adalah kamus. jika ada. .d) di mana k adalah kata dan d adalah definisi. } List Asosiasi Salah satu aplikasi pencarian yang banyak digunakan adalah yang menggunakan list asosiasi (association list). List asosiasi digunakan secara luas dalam ilmu komputer. } } // Sampai titik ini.

jmlEntri++.) Direktori telepon mungkin berupa objek di dalam kelas class DirektoriTelepon { EntriTelepon[] info = new EntriTelepon[100]. idks++) { if (nama.} Data dalam direktori telepon adalah array yang bertipe EntriTelepon[] dan variabel integer untuk menyimpan berapa banyak item yang disimpan dalam direktori tersebut. } return null. for (int idks = 0. Mungkin lebih baik jika kita menggunakan array dinamis atau ArrayList untuk menyimpan daftar telepon.equals( info[idks].nama )) // Nama ketemu! return info[idks]. // Jumlah entri aktual di dalam array void tambahEntri(String nama. info[jmlEntri]. idks < jmlEntri. info[jmlEntri]. // Nama tidak ketemu. . (Contoh ini adalah contoh dari "array setengah penuh" yang dibahas pada bagian sebelumnya.nama = nama. } String getNoTelp(String nama) { // Ambil nomor telepon dari nama ini atau // kembalikan null jika tidak ada nama ini // di dalam array.noTelp.noTelp = noTelp. String noTelp) { // Tambah entri baru di akhir array info[jmlEntri] = new EntriTelepon(). // Tempat untuk 100 entri int jmlEntri = 0.

Salah satu yang paling mudah dimengerti adalah pengurutan penyisipan (insertion sort). tidak terlalu suit untuk membuat entri tersebut dalam urutan. int jmlItem. static void sisip(int[] A. kita hanya bisa lakukan ini apabila EntriTelepon diurut terlebih dahulu berdasarkan nama. Satu hal. Kelas ini bisa diperbaliki lebih lanjut. Hal ini sering dilakukan untuk list asosiasi. Jika kita ingin memastikan bahwa suatu list tetap dalam kondisi terurut. dan semua item yang lebih besar ditempatkan setelahnya. Pengurutan Pengurutan Penyisipan (Insertion Sort) Ada banyak algoritma yang tersedia untuk melakukan pengurutan.. rutin ini tidak mengembalikan lokasi item dalam array. Akan tetapi ia mengembalikan nilai lain yang berhubungan dengan kata kuncinya. // // // Item ini harus berada dalam kondisi terurut naik di mana (A[0] <= A[1] <= . Artinya kita harus menggeser semua item yang lebih besar ke satu sisi untuk memberi ruangan pada item baru yang akan ditambahkan. dan kita ingin menambahkan sebuat item ke dalamnya.} } Lihat bahwa metode getNoTelphanya mengambil lokasi dalam array yang telah diisi dengan EntriTelepon. Akan tetapi. yang akan kita lihat berikutnya. Dan juga tidak seperti rutin pencarian yang disebutkan sebelumnya. yaitu nama. Metode ini juga bisa digunakan untuk menjaga agar list selalu dalam urutan tertentu (naik atau turun) sewaktu kita menambah item baru ke dalam list.. <= A[jmlItem-1]). int itemBaru) { // Kondisi awal : jmlItem adalah jumlah item pada A. dan semua item masih dalam kondisi terurut. // // itemBaru telah ditambah pada array. // Catatan: untuk menyelesaikan proses penyisipan item . Dan sebenarnya. yaitu semua item yang lebih kecil harus ditempatkan sebelum item tersebut. // Kondisi akhir : jumlah item akan ditambah dengan satu. Ukuran array harus lebih besar dari jmlItem. mungkin lebih baik jika kita melakukan pencarian dengan menggunakan pencarian biner dan bukan pencarian linier sederhana dalam metode getNoTelp. maka item tersebut harus diletakkan di tempat yang tepat. Mari kita lihat contoh pertama : Misalnya kita memiliki list yang sudah diurutkan.

Setiap penyisipan bisa dilakukan dengan rutin sisip() di atas.length.// // dalam array. // Letakkan itemBaru di tempat kosong } Metode di atas bisa dikembangkan menjadi metode pengurutan jika kita mengeluarkan semua item dari array yang belum diurutkan. Stop jika item yang lebih kecil ditemukan atau sampai ke awal array (lok == 0) */ while (lok >= 0 && A[lok] > itemBaru) { A[lok + 1] = A[lok]. sambil menjaga agar array tetap terurut selama kita menambah item ke array baru. kita tidak benar-benar mengambil semua item dari dalam array. itemTerurut++) { . variabel yang mencatat jumlah item dalam array harus ditambah satu setelah memanggil subrutin ini. // Jumlah item yang sudah diurut for (itemTerurut = 1. // Mulai dari akhir array /* Pindahkan item yang lebih besar dari itemBaru satu posisi. itemTerurut < A. Dalam algoritma sesungguhnya. kemudian memasukkannya kembali satu demi satu. // Pindahkan lokasi item dari posisi lok ke lok+1 lok = lok . int lok = jmlItem .1. } // Pindah ke lokasi sebelumnya A[lok + 1] = itemBaru.1. kita hanya cukup mengingat bagian mana yang sudah diurutkan. static void urutPenyisipan(int[] A) { // Mengurutkan array A dalam urutan menaik (dari kecil ke besar) int itemTerurut.

Sisipkan A[itemTerurut] // ke dalam bagian yang sudah diurutkan int temp = A[itemTerurut]. // Item yang akan disisipkan int lok = itemTerurut .. ketika itemTerurut = 5. . // Mulai dari akhir list while (lok >= 0 && A[lok] > temp) { A[lok + 1] = A[lok]. yang menunjukkan apa yang terjadi di tengah-tengah salah satu eksekusi perulangan for dari kode di atas.1. // Letakkan temp di tempat kosong } } Ilustrasi berikut adalah ilustrasi di tengah-tengah pengurutan. A[1]..// Anggap item A[0]. // Pindahkan item dari lok ke lok+1 lok = lok . A[itemTerurut-1] // telah diurutkan. .1. } // Pindah ke lokasi sebelumnya A[lok + 1] = temp.

kemudian memindahkannya ke akhir array -atau dengan kata lain di tempatnya. dan seterusnya. kemudian letakkan di tempat kedua dari akhir... kita gunakan cara yang sama. . . karena item terbesar akan berada di akhir array. Metode ini mencari item terbesar di dalam list.. A[tmptTerakhir]. A[1]. Metode ini dapat ditulis sebagai : static void urutPilihan(int[] A) { // Urut A dengan urutan menaik dengan Pengurutan Pilihan for (int tmptTerakhir = A.Pengurutan Pilihan (Selection Sort) Metode pengurutan lainnya yang biasa digunakan adalah pengurutan pilihan (selection sort). tmptTerakhir > 0. yaitu cari item terbesar berikutnya.length-1. Setelah item terbesar ditempatkan di tempat yang benar. tmptTerakhir--) { // Cari nilai terbesar di antara A[0].

Kita akan diskusikan kemudian. // Lokasi nilai terbesar saat ini for (int j = 1.// dan pindahkan ke tmptTerakhir dengan cara menukarny // dengan nilai yang ada di tmptTerakhir int lokMaks = 0. } } int temp = A[lokMaks]. Algoritma baik untuk mengocok mirip dengan pengurutan pilihan. Ada beberapa algoritma pengurutan lain yang jauh lebih cepat dari pengurutan penyisipan dan pengurutan pilihan untuk array yang sangat besar. yaitu bagaimana caranya meletakkan elemen array dengan urutan acak. A[lokMaks] = A[tmptTerakhir]. Misalnya adalah untuk mengocok kartu. Mengacak Nilai Kita akan sudahi bagian ini dengan masalah yang sedikit berkaitan. akan tetapi kita tidak memindahkan item terbesar ke array paling belakang. akan tetapi menarik. j++) { if (A[j] > A[lokMaks]) { // Karena A[j] lebih besar dari nilai maksimum yang pernah // kita lihat. A[tmptTerakhir] = temp. j <= tmptTerakhir. j adalah lokasi baru tempat di mana nilai // maksimum tersebut berada lokMaks = j. Item dipilih secara acak dan dipindahkan ke akhir array. } // akhir perulangan } Pengurutan penyisipan dan pengurutan pilihan cocok digunakan untuk mengurut array dengan ukuran kecil (hingga beberapa ratus elemen). Berikut ini adalah subrutin untuk mengocok array bertipe int. // Tukar nilainya dengan A[tmptTerakhir]. lebih jarang muncul. .

1. int lokAcak = (int)(Math. A[lokAcak] = A[tmptTerakhir]. } } Rekursi Definisi rekursi adalah definisi yang menggunakan konsep atau sebagian dari definisi tersebut menjadi definisi yang komplit. dimana beberapa file bisa berisi daftar file. A[tmptTerakhir] = temp. Misalnya : "keturunan" bisa berarti anak atau keturunan dari anak. Akan tetapi mengatakan "dan seterusnya" bukan arti "keturunan" secara lengkap. Subrutin tersebut memanggil dirinya sendiri secara tidak langsung yaitu jika ia memanggil subrutin lain yang akhirnya memanggil subrutin pertama (baik langsung maupun tak langsung). // Tukar item pada lokAcak dengan A[tmptTerakhir] int temp = A[lokAcak].length-1.random()*(tmptTerakhir+1)).. "Kalimat" bisa berarti dua kalimat yang digabung dengan kata hubung "dan". Definisi istilah "keturunan" tanpa menggunakan rekursi bisa jadi "anak.. dan seterusnya". Subrutin rekursif adalah subrutin yang memanggil dirinya sendiri. dan seterusnya". kondisi bernilai boolean dan pernyataan lainnya. Rekursi bisa digunakan dalam teknik pemrograman. "himpunan" adalah koleksi elemen.. . tmptTerakhir > 0. cucu.static void kocok(int[] A) { // Kondisi akhir : Item pada A diatur dalam urutan yang acak for (int tmptTerakhir = A. "Direktori" adalah bagian pada hard disk yang berisi file dan direktori. Definisi rekursi bisa menjelaskan situasi yang sangat kompleks dalam beberapa kata. cicit..tmptTerakhir. tmptTerakhir--) { // Pilih lokasi acak di antara 0. di mana beberapa file tersebut bisa berisi daftar file. di mana elemen tersebut bisa berupa himpunan. Kita juga akan kesulitan jika kita mencoba mendefinisikan "direktori" sebagai "file yang berisi daftar file. baik langsung maupun tak langsung. Dalam matematika. "Pernyataan" pada Java misalnya pernyataan while yang didalamnya terdapat kata while. Mencoba untuk menjelaskan pernyataan Java tanpa menggunakan rekursi dalam definisinya akan sulit dilakukan.

kita harus bisa menerapkan subrutin secara rekursif hanya sebagian dari list aslinya. Caranya adalah dengan mengecek elemen di tengah list tersebut. yang merupakan fakta tentang subrutin rekursif. Algoritma pencarian biner memiliki kasus dasar lain. bukan dilakukan secara rekursif. Pertama. maka kita harus mencari di separuh awal dari list tersebut. Pencarian biner digunakan untuk mencari suatu nilai dalam list terurut (atau jika item nilai tersebut tidak ada di dalam list tersebut. parameternya adalah suatu array. Kemudian. hingga besar list yang akan dicari berkurang menjadi 0. Berikut ini adalah algoritma pencarian biner rekursif yang mencari suatu nilai dalam bagian dari array integer: static int cariBiner(int[] A. yaitu memiliki list yang tidak kosong. Pada subrutin aslinya yang non-rekursif. Akan tetapi dalam pendekatan rekursif. Dalam subrutin non-rekursif dari pencarian biner yang dibahas sebelumnya. kita melakukan pencarian di seluruh array. maka program tersebut selesai.Suatu subrutin rekursi bisa menyelesaikan tugas kompleks dalam beberapa baris perintah. Pertimbangan kedua adalah parameter subrutin tersebut. Atau dengan kata lain. Jika nilai yang dicari lebih kecil daripada nilai elemen di tengah list tersebut. kita akan mengecek kembali elemen tengahnya. ada dua pertimbahangan yang harus kita masukkan ke dalam perhitungan kita. Apa yang terjadi jika list tersebut kosong? Jika tidak ada elemen di dalam list. Parameter subrutin tersebut harus bisa memberi tahu di bagian mana array akan dicari. int idksRendah. Jika elemen tersebut sama dengan nilai yang dicari. Jika lebih besar. ini disebut "kondisi awal" untuk mengecek elemen di tengah list. maka pencarian tersebut selesai. yaitu jika kita menemukan nilai yang kita cari di tengah suatu list. pada separuh list yang kita pilih tersebut. sedangkan subrutin rekursif harus bisa mencari di sebagian array. yang dari sini kita tahu paruh mana yang akan kita cari berikutnya. Kita akan lihat beberapa contohnya pada bagian ini. dan kita bisa membuat subrutin rekursif untuk mengimplementasikannya. Sebelumnya. Kita tidak perlu melakukan rekursi lebih lanjut. Kita akan melihat kembali apakah nilainya sama dengan nilai yang kita cari. Apa yang terjadi kita ternyata harus mencari nilai di list kosong? Jawabannya mudah : Kita bisa mengatakan bahwa nilai yang kita cari tidak ada di dalam list. int nilai) { . maka kita tidak mungkin melihat elemen di tengahnya. lebih besar atau lebih kecil. Mari kita mulai dengan contoh yang sudah kita lihat sebelumnya: algorithma pencarian biner pada bagian sebelumnya. kita harus mencari di separuh akhir list tersebut. Dan begitu seterusnya. algoritma pencarian biner dimulai dengan mengecek "elemen tengah suatu list". List kosong adalah kasus dasar untuk algoritma pencari biner. Kasus dasar untuk algoritma rekursif adalah kasus yang akan ditangani secara langsung. int idksTinggi. akan memberitahu hasilnya misalnya dengan mengembalikan -1). Ini adalah definisi rekursif.

else if (nilai < A[idksTengah]) return cariBiner(A.yaitu tidak ada elemen di dalam rentang indeks yang diberikan dan ketika tidak ada nilai yang ditemukan di tengah-tengah rentang tersebut -- . // Jika tidak. cari secara rekursif di awal atau akhir // dari setengah list int idksTengah = (idksRendah + idksTinggi) / 2. 0. parameter idksRendah dan idksTinggi menyatakan bagian array yang akan dicari. kita hanya perlu memanggil cariBiner(A.length 1. else // nilai > A[idksTengah] return cariBiner(A. nilai). idksTinggi. } else { // Cek elemen di tengah list. nilai).1. if (nilai == A[idksTengah]) return idksTengah. A. idksTengah + 1. nilai).// Cari "nilai" pada array "A" dari posisi "idksRendah" ke "idksTinggi". } } // akhir cariBiner() Dalam rutin di atas. "Nilai" tidak mungkin ada di list kosong. maka kembalikan posisi tersebut. Untuk mencari keseluruhan array. idksRendah. Jika nilai sama dengan isi elemen // tengah. idksTengah . return -1. // Asumsinya adalah array diurut dalam urutan menaik // Jika nilai ditemukan kembalikan indeks pada array // dimana nilai tersebut berada. Jika tidak kembalikan -1 if (idksRendah > idksTinggi) { // Artinya list kosong karena seharusnya idksRendah lebih rendah // dari idksTinggi. Dalam kedua kasus dasar -.

yang bisa ditangani tanpa menggunakan rekursi. makin kecil hingga mendekati kasus dasarnya. subrutin akan memanggil dirinya sendiri secara rekursif untuk menghitung dan mengembalikan hasilnya. Ada tiang lain yang berfungsi sebagai tiang cadangan. • • . Kuncinya ada 2 hal yang harus dipenuhi agar rekursi bisa bekerja dengan benar : Harus ada minimum satu kasus dasar. dan bisa digunakan sebagai tempat sementara. hasilnya bisa jadi rekursi tak hingga. Pada kasus lain. dan piringan yang lebih besar tidak boleh diletakkan di atas piringan yang lebih kecil. di mana subrutin tersebut akan memanggil dirinya terus menerus tanpa henti. Gambar lainnya (bawah) adalah ilustrasi setelah beberapa langkah telah dijalankan. Sekarang mari kita lihat suatu masalah yang lebih mudah diselesaikan dengan rekursi tapi sulit dilakukan dengan metode lain. Gambar berikut (atas) mengilustrasikan tumpukan 10 piringan. Akan tetapi karena setiap panggilan rekursif menggunakan memori komputer. • • Pencarian biner dapat diimplementasikan dengan perulangan while selain dengan menggunakan rekursi. Jika aturan ini dilanggar. dengan dua aturan dalam setiap langkah hanya boleh memindahkan satu piringan. Seluruh piringan harus dipindahkan dari satu tiang ke tiang lain.subrutin dapat memberikan jawabannya secara langsung. Jika subrutin dilakukan secara rekursif. maka program yang tersangkut di dalam rekursi tak hingga. Rekrusi tak hingga mirip dengan perulangan yang tak pernah berhenti. Banyak orang yang merasa sulit untuk memahami bagaimana rekursi bekerja. pada akhirnya akan kehabisan memori. karena tidak pernah mencapai kasus dasarnya. ia harus dipanggil dalam lingkup yang lebih kecil. tanpa rekursi. Satu kesalahan umum yang terjadi ketika menulis subrutin rekursif adalah jika kita melanggar salah satu dari kedua aturan di atas. yand dinamakan "Menara Hanoi". Berikut ini adalah contoh yang biasa digunakan. Persoalannya dapat dituliskan sebagai berikut : sebuah tumpukan piringan dengan ukuran berbeda ditumpuk dari urutan terbesar di bagian paling bawah hingga terkecil di bagian paling atas.

Kita akan memindahkan 10 piringan dari tiang 0 ke tiang 1, dan tiang 2 bisa dijadikan cadangan. Bisakah kita mengurangi persoalan ini menjadi persoalan yang sama dengan skala yang lebih kecil? Mungkin kita harus sedikit mengeneralisir persoalannya sehingga kita bisa melihat lebih jelas. Jika ada N piringan pada tiang 0, kita tahu bahwa pada akhirnya kita haris memindahkan piringan paling bawah dari tiang 0 ke tiang 1. Akan tetapi sebelum itu, menurut aturan di atas, piringan 0 hingga N-1 harus dipindahkan terlebih dahulu ke tiang 2. Setelah kita pindahkan piringan ke-N ke tiang 1, maka kita harus memindahkan kembali N-1 piringan dari tiang 2 ke tiang 1 untuk menyelesaikan masalahnya. Lihat bahwa memindahkan N-1 piringan adalah persoalan yang sama seperti memindahkan N piringan, akan tetapi sekarang persoalannya menjadi lebih kecil. Ini bisa dilakukan dengan mudah dengan rekursi. Suatu persoalan harus digeneralisir terlebih dahulu, di sini kita lihat bahwa persoalan yang lebih kecil adalah memindahkan piringan dari tiang 0 ke tiang 2 dan kemudian dari tiang 2 ke tiang 1, bukan dari tiang 0 ke tiang 1. Untuk subrutin rekursiif yang akan kita buat, kita harus menyatakan tiang asal, tiang tujuan, dan tiang cadangannya. Kasus dasarnya adalah jika hanya ada satu piringan yang akan dipindahkan, yang mana jawabannya mudah : pindahkan satu piringan itu dalam satu langkah. Berikut ini adalah contoh subrutin untuk menyelesaikan masalah ini : void MenaraHanoi(int piringan, int asal, int tujuan, int cadangan) { // Memecahkan persoalan untuk memindahkan sejumlah "piringan" // dari tiang "asal" ke tiang "tujuan". Tiang "cadangan" bisa

// digunakan sebagai tempat sementara if (piringan == 1) { // Hanya ada satu piringan, pindahkan langsung System.out.println("Pindahkan piringan dari tiang " + asal + " ke tiang " + tujuan); } else { // Pindahkan semua piringan minus 1 ke tiang cadangan, // kemudian pindahkan piringan paling bawah ke tiang tujuan, // kemudian pindahkan sisanya dari tiang cadangan ke // tiang tujuan. MenaraHanoi(piringan-1, asal, cadangan, tujuan); System.out.println("Pindahkan piringan dari tiang " + asal + " ke tiang " + tujuan); MenaraHanoi(piringan-1, cadangan, tujuan, asal); } } Subrutin ini mengekspresikan solusi persoalan secara alami. Rekursi bisa bekerja dengan benar karena setiap panggil rekursif selalu akan dipanggil dengan jumlah piringan yang semakin sedikit. Dan ketika sampai pada kasus dasarnya, yaitu hanya ada satu piringan, persoalannya bisa diselesaikan langsung dengan memindahkan satu piringan tersebut ke tiang tujuannya. Untuk memecahkan persoalan ini pada "level paling atas", yaitu memindahkan N piringan dari tiang 0 ke tiang 1, subrutin ini bisa dipanggil dengan perintah MenaraHanoi(N,0,1,2). Ceritanya, dahulu kala ada kisah yang merupakan nama dari persoalan ini. Menurut cerita ini, pada saat bumi pertama kali dicipkatan, sekumpulan biksu pada suatu menara di dekat Hanoi diberi tumpukan 64 piringan dan diberi tugas untuk memindahkan satu piringan setiap hari dengan aturan yang sama seperti di atas. Pada hari ketika tugas ini selesai, alam semesta akan kiamat. Tapi tenang saja, karena jumlah langkah yang diperlukan untuk menyelesaikan tugas ini untuk N piringan adalah 2N - 1, dan 264 - 1 hari sama dengan lebih dari 50 trilyun tahun.

Pengurutan Cepat
Aplikasi rekursi yang cukup populer adalah Pengurutan Cepat (Quicksort) yang digunakan untuk mengurutkan array. Di bagian sebelumnya kita telah melihat bagaimana mengurutkan array dengan menggunakan pengurutan pilihan dan pengurutan penyisipan yang relatif lebih mudah, akan tetapi akan berjalan lebih lambat untuk array yang besar. Algoritma pengurutan yang lebih cepat sudah tersedia. Salah satunya adalah pengurutan cepat (quick sort), yaitu algoritma rekursif yang ternyata paling cepat hampir pada segala kondisi. Algoritma pengurutan cepat dibuat berdasarkan ide yang sederhana namun cerdas : Dari beberapa item, pilih satu item. Item ini kita sebut pivot. Pindahkan semua item yang lebih kecil dari pivot ke awal array, dan pindahkan item yang lebih besar ke akhir array. Kemudian letakkan pivot di tengah-tengah kedua grup tersebut. Atau dengan kata lain, posisi pivot adalah posisi terakhir dan tidak perlu dipindahkan lagi.

LangkahUrutCepat bukan algoritma rekursif. Kecepatan pengurutan cepat tergantung dari kecepatan LangkahUrutCepat. Karena ini bukan diskusi utama kita, kita akan tuliskan algoritma LangkahUrutCepat tanpa diskusi lebih lanjut. static int LangkahUrutCepat(int[] A, int rendah, int tinggi) { // Jalankan LangkahUrutCepat pada array dengan indeks // antara rendah dan tinggi pada array A. Nilai yang dikembalikan // adalah posisi akhir pivot dalam array

// Kita ambil sembarang pivot, yaitu pada indeks pertama int pivot = A[rendah];

// Nilai antara rendah dan tinggi adalah nilai yang belum pernah // kita uji. Kurangi tinggi dan naikkan rendah hingga keduanya // bernilai sama, pindahkan nilai yang lebih besar dari pivot // sehingga nilai tersebut berada di atas tinggi dan pindahkan // nilai yang lebih kecil dari pivot sehingga nilainya berada // di bawah rendah. Ketika kita mulai, A[rendah] adalah tempat // kosong, karena ini adalah posisi awal nilai pivot

while (tinggi > rendah) {

while (tinggi > rendah && A[tinggi] > pivot) { // Pindahkan tinggi hingga melewati nilai yang lebih rendah // dari pivot. Nilai ini tidak perlu dipindahkan hi--; }

if (tinggi == rendah) break;

// Nilai pada A[tinggi] kurang dari pivot. Pindahkan ke tempat // kosong pada A[rendah], sehingga tempat di A[tinggi] // menjadi kosong

A[rendah] = A[tinggi]; rendah++;

while (tinggi > rendah && A[rendah] < pivot) { // Pindahkan rendah hingga melewati nilai yang lebih tinggai // pivot. Nilai ini tidak perlu dipindahkan rendah++; }

if (tinggi == rendah) break;

// Nilai A[rendah] lebih tinggi dari pivot. Pindahkan ke tempat // kosong pada A[tinggi], sehingga tempat di A[rendah] // menjadi kosong.

A[tinggi] = A[rendah]; tinggi--;

} // akhir while

// Di sini, rendah sama dengan tinggi, dan ada tempat kosong // di sini. Posisi ini berada di antara nilai yang lebih tinggi dan // nilai yang lebih rendah dari pivot. Letakkan pivot di sini // dan kembalikan posisinya.

A[rendah] = pivot; return rendah;

} // akhir LangkahUrutCepat Degan subrutin ini, maka pengurutan cepat mudah dilakukan. Algoritma untuk mengurutkan deretan nilai yaitu dengan menjalankan LangkahUrutCepat pada nilai-nilai tersebut, kemudian menjalankan pengurutan cepat secara rekursif terhadap item yang ada di sebelah kiri pivot dan item yang ada di sebelah kanan pivot. Tentunya kita juga membutuhkan kasus dasar. Yaitu jika list hanya memiliki satu item atau kosong, maka list tersebut telah diurutkan. static void urutcepat(int[] A, int rendah, int tinggi) { // Jalankan pengurutan cepat untuk mengurutkan array // antara posisi rendah dan posisi tinggi dalam urutan naik if (tinggi <= rendah) { // List memiliki panjang nol atau 1. Tidak ada yang perlu // dilakukan, jadi kita keluar dari subrutin return; } else { // Jalankan LangkahUrutCepat dan dapatkan posisi pivot // Kemudian jalankan urutcepat untuk mengurut item sebelum // pivot dan item setelah pivot int posisiPivot = LangkahUrutCepat(A, rendah, tinggi); urutcepat(A, rendah, pivotPosition - 1); urutcepat(A, pivotPosition + 1, tinggi); } } Seperti biasa, kita telah melihat masalah dengan mengeneralisirnya. Masalah awalnya adalah untuk mengurutkan array, akan tetapi algoritma rekursif dibuat untuk mengurutkan sebagian array. Untuk mengurut keseluruhan array A, kita bisa menggunakan urutcepat() yaitu dengan perintah urutcepat(A, 0, A.length -1).

Struktur Data Berantai
Pada bagian ini kita akan melihat teknik pemrograman tingkat lanjut lainnya, yaitu struktur data berantai (linked data structure), dan applikasinya.

Suatu referensi ke suatu objek bisa disimpan sebagai variabel instansi di objek lain, sehingga "terkait" satu sama lain. Struktur data kompleks bisa dibuat dengan mengaitkan satu objek dengan objek lainnya menjadi struktur data berantai. Yang menarik adalah apabila objek ini dikaitkan dengan objek lain yang memiliki kelas yang sama. Di sini kelas tersebut digunakan dalam definisi kelas yang sama. Beberapa jenis struktur data bisa dibuat dengan menggunakan model semacam ini.
• • • • •

Mengaitkan Objek Tumpukan Antrian Pohon Biner Pohon Pengurutan Biner

Mengaitkan Objek
Hampir semua objek memiliki variabel instansi. Jika variabel instansi bertipe suatu kelas atau interface, maka variabel instansi itu bisa menyimpan referensi ke objek lain. Referensi disebut juga pointer, karena referensi menunjuk pada suatu objek. (Variabel yang berisi referensi ke suatu objek juga bisa berisi null alias tidak menunjuk ke mana-mana). Jika satu objek memiliki referensi ke objek lain, objek itu disebut terkait satu sama lain. Struktur data kompleks bisa dibuat dengan mengaitkan objek satu sama lain. Jika suatu objek memiliki pointer ke objek lain dengan tipe yang sama, maka definisi kelasnya bersifat rekursif. Rekursi jenis ini banyak terjadi, misalnya kelas Pegawai yang melambangkan pegawai di suatu perusahaan. Semua orang kecuali bos tertinggi memiliki atasan, di mana atasannya ini adalah juga pegawai perusahaan tersebut. Tentunya kelas Pegawai memiliki variabel instansi dengan tipe Pegawai yang menunjuk pada atasan pegawai itu, sehingga :
class Pegawai { // Objek untuk menyimpan data tentang seorang pegawai String nama; // Nama pegawai Pegawai atasan; // Atasan pegawai ini . . // (Metode dan variabel instansi lain.) . } // akhir kelas Pegawai

Jika pgw adalah variabel bertipe Pegawai, maka pgw.atasan adalah variabel lain yang juga bertipe Pegawai. Jika pgw menunjuk pada bos tertinggi, maka pgw.atasan berisi null yang artinya ia tidak memiliki atasan. Kita bisa mencetak nama atasan seorang pegawai, misalnya dengan pernyataan Java berikut :
if ( pgw.atasan == null) { System.out.println( pgw.nama " adalah bos tertinggi." ); } else { System.out.print( "Atasan dari " + pgw.nama + " ialah " ); System.out.println( pgw.atasan.nama ); }

Sekarang, misalnya kita ingin tahu berapa tingkat di atas seorang pegawai hingga sampai pada bos tertinggi. Jika bisa melacak atasan dari atasannya, dan seterusnya, hingga sampai pada bos

println( pgw. sehingga sering digunakan sebagai topik pembahasan dalam ilmu komputer.nama + " memiliki atasan langsung bos tertinggi.out. while ( pointer. variabel atasan terlihat natural dan berfungsi dengan baik. } System. } else { int level = 0. kemudian atasannya lagi.atasan != null ) { level++. kita akan melihat yang dinamakan list berantai (linked list).atasan == null ) { System. if ( pointer.atasan. level telah mencatat berapa level yang dibutuhkan dari pgw ke bos tertinggi. pointer akan menunjuk pada atasan pgw. // Level atasan pointer = pointer. Sebenarnya. // Untuk menunjuk pada urutan bos. dan seterusnya.nama + " dan bos tertinggi.atasan berisi null yang artinya pointer telah sampai pada bos tertinggi." ). Dalam contoh ini.nama " adalah bos tertinggi.out." ).out. Pada saat itu. Perulangan selesai ketika pointer.supervisor." ).tertinggi. pointer = pgw.println( "Ada " + level + " atasan antara " + pgw. Kita akan melihat beberapa contohnya. } } Ketika perulangan while dieksekusi. struktur data yang dibangun dengan mengaitkan objek satu sama lain sangat berguna. . Variabel level dinaikkan 1 setiap kali pointer menunjuk pada atasan baru. } else { Pegawai pointer. kemudian menghitung berapa langkah yang diperlukan hingga sampai ke bos tertinggi itu: if ( pgw.println( pgw. Pada bagian ini dan berikutnya.atasan == null) { System.

yang terkait oleh pointer dari satu objek ke objek lain. dan mencari String pada item di dalam list. .List berantai merupakan rantai objek yang bertipe sama. Kita akan lihat contohnya di bagian berikutnya. Objek dengan tipe Simpul bisa disambung seperti pada gambar di atas. kita bisa menggunakannya untuk mengilustrasikan operasi umum pada list berantai. list berantai akan dibuat dari objek yang bertipe Simpul yang didefinisikan sebagai berikut : class Simpul { String item. menyisipkan simpul baru ke dalam list. Simpul berikut. Meskipun Simpul pada contoh ini terlihat sederhana. Di bagian ini. Operasi umumnya meliputi menghapus simpul dari list. program tersebut perlu variabel untuk menunjuk pada simpul pertama dari list. karena simpul lainnya bisa dicari dari simpul tertama kemudian mengurutkan melalui pointer ke simpul berikutnya. Agar list berantai bisa digunakan dalam program. Mirip dengan hirarki organisasi antara pgw hingga bos tertinggi pada contoh di atas. Kita bisa juga memiliki siatuasi yang lebih kompleks di mana satu objek berisi pointer ke beberapa objek. } Istilah simpul sering digunakan untuk menyebut salah satu objek di dalam struktur data berantai. Variabel itu hanya perlu menunjuk pada simpul pertama. Simpul terakhir dalam list tersebut bisa ditentukan apabila variabel instansi berikut berisi null. Kita akan lihat beberapa subrutin yang melakukan operasi ini.

kita cukup menggunakan perintah pointer = pointer. kita akan menggunakan variabel bertipe Simpul yang bernama pointer untuk digunakan sebagai penunjuk ke simpul-simpul yang akan kita lihat. // Mulai dari simpul pertama. jadi kita bisa mulai dengan mengisi pointer dengan isi kepala. .equals(itemDicari) ) return true.berikut. itemDicari ada di salah satu simpul di dalam list. kita akan kehilangan jejak list yang kita buat. Kita akan tahu bahwa kita telah sampai pada akhir list jika pointer bernilai null. . Semuanya bisa kita tuangkan dalam metode instansi cari() pada kelas ListString sebagai berikut : public boolean cari(String itemDicari) { // Kembalikan true jika itemDicari ada di dalam list // false jika tidak ada dalam list.item. Kita harus membuat variabel baru ini karena kita akan mengganti isinya pada saat melakukan pencarian. public class ListString { Simpul kepala. jika tidak // teruskan pencarian di simpul berikutnya if ( pointer. Kita tidak bisa mengganti isi kepala. pointer = pointer. maka kepala berisi null. Variabel ini bertipe Simpul dan menyimpan referensi ke simpul pertama dari list berantai. kembalikan true. Simpul pointer = kepala. // metode dan variabel instansi lainnya } Misalnya kita ingin tahu apakah suatu string. Kita hanya bisa mengakses list melalui variabel kepala. // Pointer untuk menelusuri list pointer = kepala. karena jika kita ganti.Kita bisa membuat objek baru dengan misalnya bernama "ListString" yang memiliki variabel instansi bernama "kepala". .berikut. Caranya. Simpul pointer. // Pindah ke simpul berikutnya .. // Mulai pencarian dari kepala list (kepala adalah variabel instansi) while ( pointer != null ) { // Lihat isi simpul satu per satu. Jika isinya sama dengan // yang kita cari. Jika listnya kosong. Kita bisa membandingkan itemDicari dengan isi setiap simpul di dalam list. Untuk pindah dari satu simpul ke simpul berikutnya.

item tersebut harus ditempatkan pada posisi yang tepat sesuai urutannya. // Kembalikan false. di mana masing-masing menunjuk pada 2 posisi di mana item baru akan disisipkan di antaranya. Dalam kelas ListString. Untuk melakukan penyisipan. Supaya mudah. Jika suatu item ditambahkan ke dalam list. . pointer = pointer. karena kondisi perulangan hanya bisa dijalankan apabila pointer bernilai null. maka badan perulangan while tidak akan dieksekusi sama sekali. . } // akhir cari() Pola di atas akan sering digunakan nanti: Jika kepala adalah variabel yang menunjuk pada suatu list berantai. Pada ilustrasi berikut. Dalam contoh kode di atas. dan kait baru dari sebelum ke simpulBaru dan dari simpulBaru ke pointer harus dibuat. variabel ini adalah sebelum dan pointer. kita harus menyisipkan item baru ditengah-tengah list. Variabel lain. return false. // proses simpul yang ditunjuk oleh pointer . kita bisa lakukan dengan : pointer = kepala. while ( pointer != null ) { . Artinya. kita membutuhkan dua variabel dengan tipe Simpul. } Mungkin saja listnya kosong. item pada simpul dibuat dalam urutan menaik. yang artinya kita tidak menemukan item ini. maka untuk proses semua simpul dalam list. yaitu apabila isi kepala adalah null.berikut. yaitu simpulBaru menyimpan referensi ke simpul baru yang akan disisipkan. di antara dua simpul yang sudah ada. Menyisipkan item baru ke dalam list sedikit lebih sulit. hubungan antara sebelum dan pointer harus diputus. kita telah sampai pada akhir list // akan tetapi tidak ada item yang kita cari.} // Di sini. jika kepala berisi null.

Ini bisa dilakukan dengan instruksi berikut : simpulBaru. Kita akan mulai dari awal list.berikut. Dan perintah "simpulBaru.Perintah "sebelum.compareTo(sisipItem) < 0 ) { sebelum = pointer. // bisa juga menggunakan "sebelum = sebelum. sebelum.item.berikut = kepala.berikut menunjuk pada simpul baru. hati-hati bahwa kita bisa sampai di akhir list tanpa kita sadari. kita harus menempatkan posisi sebelum dan pointer pada tempat yang benar terlebih dahulu (seperti pada ilustrasi di atas). // Buat simpulBaru sebagai kepala list yang baru .berikut" pointer = pointer. // Buat simpulBaru. Artinya kita tidak bisa meneruskan lagi apabila pointer sampai ke akhir list.berikut menunjuk pada pointer. akan tetapi asumsi kita untuk menyisipkan node baru di tengahtengah list tidak selamanya benar. kemudian pindah ke simpul berikutnya selama isinya lebih kecil dari item baru. } (Kode di atas menggunakan compareTo() dari kelas String untuk menguji apakah item di dalam node bernilai kurang dari item yang akan disisipkan. maka kita asumsikan bahwa item ini harus berada di dalam list.next bernilai null.next menunjuk kepala lama kepala = simpulBaru. // Mulai di awal list pointer = kepala. yaitu ketika pointer.berikut = pointer" digunakan untuk membuat simpulBaru. sebelum = kepala. Kode berikut akan menempatkan posisi sebelum dan pointer dengan tepat: Simpul pointer. while ( pointer != null && pointer.) Kode di atas boleh-boleh saja. Artinya. Jika sisipItem adalah item item yang akan disisipkan." digunakan untuk membuat sebelum.berikut. Akan tetapi. Mungkin saja sisipItem lebih kecil dari item pertama. simpul baru harus disisipkan pada kepala list.berikut = simpulBaru. Ketika kita memindahkan pointer dari satu tempat ke tempat berikutnya. sebelum kita menjalankan perintah ini.

Akan tetapi. } } // akhir sisip() Jika Anda memperhatikan dengan seksama diskusi di atas. ketika ini terjadi. Metode sisip() berikut ini merangkum semua kemungkinan di atas : public void sisip(String sisipItem) { // Tambah sisipItem ke dalam list. Sebenarnya.berikut. sebelum masih tetap menunjuk pada item terakhir pada list. .Atau bisa saja listnya kosong. // Simpul yang menunjuk pada posisi sebelum pointer sebelum = kepala. } simpulBaru. // Simpul untuk menelusuri list Simpul sebelum. pointer menunjuk // pada posisi di mana sisipItem akan disisipkan sebelum = pointer. yaitu di bagian akhir pernyataan if . isi simpulBaru. Setelah perulangan selesai. while (pointer != null && pointer.compareTo(sisipItem) >= 0 ) { // Item baru kurang dari item pertama list // Jadi item baru harus disisipkan sebelum kepala list simpulBaru.berikut = kepala. Artinya. // Simpul baru yang berisi item baru simpulBaru = new Simpul().berikut = simpulBaru. Apa yang terjadi jika simpul baru harus disisipkan di akhir list? Ini terjadi jika semua item di dalam list lebih kecil daripada item baru. simpulBaru. Ini bisa dilakukan dengan mengisi kepala = simpulBaru.item = sisipItem. Boleh menyisipkan // kopi yang sama Simpul simpulBaru. kepala = simpulBaru. } else if ( kepala. // (N. mungkin Anda akan ingat bahwa ada satu kasus lagi yang tidak pernah disebutkan.berikut.berikut = pointer. Jika sisipItem lebih besar dari semua item di dalam list. // Set sebelum ke kepala list dan pointer ke posisi setelahnya pointer = kepala.berikut = simpulBaru menambahkan simpul baru di akhir list.berikut masih null) if ( kepala == null ) { // List masih kosong // Buat kepala menunjuk ke simpulBaru kepala = simpulBaru.item. kasus ini sudah ditangani dengan benar oleh subrutin. Cari posisi yang tepat dan sisipkan di sana Simpul pointer. } else { // Item baru akan disisipkan di tengah-tengah list setelah // item pertama.compareTo(sisipItem) < 0) { // Pindahkan sebelum dan pointer ke posisi berikutnya hingga pointer // sampai di akhir list atau sampai pada item yang isinya lebih besar // dari sisipItem. // Sisipkan simpulBaru setelah "sebelum" sebelum. maka perulangan while akan berhenti ketika pointer selesai menelusuri sampai pada akhir list hingga pointer bernilai null.item. simpulBaru menjadi simpul pertama dan satu-satunya di dalam list. pointer = pointer.B. Perintah sebelum.

Cari itemnya di dalam list. dan sebelum menunjuk pada simpul sebelumnya.equals(hapusItem) ) { // Jika hapusItem ada pada simpul pertama.berikut dengan null. kepala = kepala. Masih ada beberapa kasus khusus yang harus dipikirkan. Jika string tidak ditemukan kembalikan false. pointer menunjuk pada posisi di mana hapusItem // seharusnya berada (jika ada) sebelum = pointer.item. null adalah nilai yang tepat untuk menandakan akhir list. Ketika satu-satunya item ini dihapus.berikut adalah simpul berikutnya. hapus. perhatikan bahwa perintah ini juga berlaku jika kepala. Simpul yang dihapus akan diambil oleh pemulung memori.item. Simpul pointer. return true. sudah pasti tidak ada string hapusItem return false. maka ini bisa dilakukan dengan perintah kepala = kepala. yaitu ketika hanya ada satu item di dalam list. (Jika ada beberapa item dengan isi yang sama.berkut berisi null[code]. Ketika simpul pertama akan dihapus. Setelah diposisikan dengan benar. hapus.berikut. } if ( pointer != null && pointer. } else if ( kepala. } else { // Di sini.equals(hapusItem) ) { // Pointer menunjuk pada simpul yang akan dihapus // Hapus dengan mengubah simpul sebelumnya .berikut. maka kita bisa membuat variabel sebelum dan pointer di mana pointer menunjuk pada simpul yang akan dihapus. perintah "sebelum. maka isi kepala harus diubah ke simpul kedua. // Simpul untuk menelusuri list Simpul sebelum.Karena isi pointer adalah null. // Mulai dari awal list pointer = kepala. maka list bernilai [code]null yang artinya list sudah kosong. Kembalikan true jika string ditemukan dan dihapus.) Jika simpul yang akan dihapus ada di tengah-tengah list.item. maka perintah [code]simpulBaru.berikut" akan menghapus simpul tersebut.berikut = pointer. Berikut ini adalah kode lengkap dari metode hapus() : public // // // // // boolean hapus(String hapusItem) { Jika hapusItem ada dalam list. meskupun sedikit lebih mudah. maka ada kemungkinan string terdapat // di tengah-tengah list. while (pointer != null && pointer. Karena kepala.compareTo(hapusItem) < 0) { // Pindahkan sebelum dan pointer di dalam list hingga // pointer sampai pada akhir list atau sampai pada item yang // lebih besar atau sama dengan hapusItem. // Selalu menunjuk pada simpul sebelum pointer sebelum = kepala. Operasi untuk menghapus mirip dengan operasi menyisipkan item. Ketika perulangan // selesai. hanya hapus yang pertama) if ( kepala == null ) { // Jika list kosong.berikut.berikut = pointer akan mengisi simpulBaru.berikut. (Sekali lagi. pointer = pointer.

hapus. istilah untuk mengeluarkan item dari tumpukan disebut "pop"). } } } // akhir hapus() Tumpukan List berantai adalah salah satu jenis struktur data. Pada bagian sebelumnya. Kita bisa juga mengimplementasikan operasi sisip. yang tersusun dari objek yang terkait satu sama lain oleh pointer. dan kita juga mengimplementasikan operasi sisip. akan tetapi antar muka dan perilakunya akan tetap sama. .berikut. list terurut berisi string bisa diimplementasikan dalam bentuk list berantai atau array. Mari kita anggap bagian ini sebagai studi kasus dari TDA. Istilah tipe data abstrak (abstract data type. Suatu "list terurut yang berisi string" adalah contoh tipe data abstrak. program bisa lebih mudah untuk dipelihara dan didebug. kita menggunakan list berantai untuk menyimpan String terurut. mirip seperti tumpukan boks. Tumpukan (stack) terdiri dari kumpulan item yang disusun sedemikian rupa sehingga satu item ditumpuk di atas item lainnya. Lebih jauh. Ada banyak cara untuk mengimplementasikan tipe data abstrak yang sama. return true. kita akan lihat TDA lain. atau ADT) adalah kumpulan nilai dan operasi yang bisa dilakukan pada nilai tersebut. Hanya item paling atas yang bisa diakses pada suatu saat. tanpa perlu mengetahui bagaimana nilai tersebut disimpan dan bagaimana operasi tersebut diimplementasikan. TDA adalah alat penting dalam rekayasa perancang lunak.berikut= pointer. Pada bagian ini dan yang akan datang. misalnya seperti disebut di atas. Suatu item hanya bisa ditambahkan di atas tumpukan dengan perintah "dorong" (atau "push"). Program yang menggunakan tipe data ini bisa menggunakannya tanpa mengetahui dengan detail tentang implementasinya. akan tetapi ini bukan satu-satunya cara implementasi. Tumpukan dan antrian sering diimplementasikan dalam bentuk list berantai. hapus dan cari pada list tersebut. dan cari. yaitu tumpukan dan antrian.sebelum. Dengan cara ini. implementasi TDA bisa diganti tanpa mempengaruhi jalannya program secara keseluruhan. } else { // Item yang dicari tidak ada return false. Implementasi operasi tersebut akan berbeda. Item tersebut bisa diambil dari tumpukan dengan operasi yang disebut "ambil" (atau dalam bahasa Inggris. Akan tetapi kita juga bisa menyimpan list String pada array atau ArrayList. Item di bawah hanya bisa diambil jika semua item di atasnya telah dikeluarkan dari tumpukan.

Lihat . tumpukan atas adalah simpul kepala dari list. Kita perlu operasi lain untuk mengujinya. Berikut ini adalah kelas "tumpukan int" yang mengimplementasikan TDA menggunakan list berantai. akan tetapi gambar tumpukan di dalam imaginasi kita akan tetap sama. Kita bisa menambah dan mengurangi simpul pada kepala list berantai -.jauh lebih mudah daripada menyisipkan atau menghapus simpul dari tengah-tengah list.Kita bisa membuat tumpukan dari berbagai macam data. TDA ini bisa diimplementasikan dengan berbagai cara. Pada implementasi dengan list berantai. sebagai tipe data abstrak. maka operasi dorong dan keluar bisa diimplementasikan dalam metode instansi void dorong(int itemBaru) // Tambah itemBaru di atas tumpukan int ambil() // Mengambil int paling atas pada tumpukan Kita tidak bisa mengambil item dari tumpukan yang kosong. jadi kita juga perlu memberi tahu apakah suatu tumpukan kosong atau tidak. jika itemnya bertipe int. yang diimplementasikan dalam metode instansi boolean isKosong() // Kembalikan true jika tumpukan kosong Ilustrasi berikut menggambarkan tumpukan int. Misalnya. (Kelas ini menggunakan kelas bertingkat sebagai kelas simpul dari list berantai.

item = N. Jika Anda masih belum paham atau merasa tidak nyaman menggunakan kelas bertingkat. // Simpul baru menunjuk pada atas lama atas = atasBaru. Simpul berikut. public void dorong( int N ) { // Letakkan N di tumpukan paling atas Simpul atasBaru. atasBaru.bagian sebelumnya tentang kelas bertingkat. // Simpan N di simpul baru atasBaru. // Simpul baru untuk menyimpan item baru atasBaru = new Simpul(). } // Referensi ke simpul paling atas dari tumpukan // jika atas == null.) public class TumpukanInt { private static class Simpul { // Objek dengan tipe Simpul menyimpan // satu item di dalam list berantai int item.berikut = atas. Anda bisa juga memisahkannya sebagai kelas terpisah. maka tumpukan tidak berisi // apa-apa (kosong) private Simpul atas. } // Simpul baru sekarang menjadi atas public int ambil() { .

item. Program yang menggunakan kelas ini tidak perlu tahu bahwa list berantai digunakan dalam implementasinya. sedangkan item atas . 1.berikut.. Jika kita tidak ingin memberi limit banyaknya item di dalam tumpukan. Jika variabel ini kita namakan atas. maka item akan disimpan dalam tumpukan pada posisi 0. Karena banyaknya item di dalam tumpukan bervariasi dan tidak bisa ditentukan. Berikut ini adalah implementasi kelas TumpukanInt dengan menggunakan array dinamis: .1 adalah item paling atas. // Item yang akan diambil atas = atas. bukan hanya list berantai. Item pada posisi 0 adalah item paling bawah dalam tumpukan. kita bisa juga mengimplementasikan tumpukan dalam bentuk array. atas . kita bisa meletakkan item di posisi atas kemudian nilai atas ditambahkan 1.. Mungkin sedikit oret-oretan akan membantu. ..// Ambil item paling atas dari dalam tumpukan // dan kembalikan nilainya. } // Item yang dulunya di posisi kedua sekarang di atas public boolean isKosong() { // Kembalikan true jika tumpukan kosong.1. kita bisa menggunakan array dinamis yang telah dibahas sebelumnya. } } // akhir kelas TumpukanInt Anda perlu memahami bagaimana operasi dorong dan ambil dilaksanakan. Catatan bahwa rutin ini akan // melempar NullPointerException jika kita mencoba untuk // mengambil item dari tumpukan kosong int itemAtas = atas. Sekarang. maka kita perlu memiliki variabel lain yang melacak berapa banyak tempat dalam array yang sudah digunakan. return itemAtas. Lihat bahwa list berantai merupakan bagian private dari kelas TumpukanInt. Untuk mendorong item baru ke dalam tumpukan. // Kembalikan false jika ada satu atau lebih item di dalam tumpukan return (atas == null).

arraycopy(item.length).1] // Item teratas di dalam tumpukan atas--. } item[atas] = N. // Banyaknya item dalam tumpukan public void dorong( int N ) { // Tambahkan N ke dalam tumpukan if (atas == item. 0.public class TumpukanInt { private int[] item = new int[10]. // Letakkan N di tempat kosong berikutnya atas++. arrayBary. item. // Jumlah item dalam tumpukan berkurang 1 .length ]. 0. System.length) { // Array sudah penuh. // Menyimpan item dalam tumpukan private int atas = 0. } // Jumlah item bertambah 1 public int ambil() { // Mengambil item teratas dari tumpukan dan mengembalikannya // Ingat bahwa rutin ini akan melempar pengecualian // ArrayIndexOutOfBoundsException jika mencoba mengambil // item dari tumpukan kosong int itemAtas = item[top . item = arrayBaru. jadi buat array yang lebih besar dan // kopi isi tumpukan sekarang ke dalam array baru int[] arrayBary = new int[ 2*item.

yaitu jika mencoba mengambil item dari tumpukan kosong.return itemAtas. Catatan aktivasi ini ditempatkan dalam tunpukan. Ketika subrutin dipanggil. dan seterusnya. Mungkin akan lebih baik untuk mendefinisikan jenis pengecualian baru. Sekarang. } } // akhir kelas TumpukanInt Sekali lagi. Catatan aktivasi ini berisi informasi yang relevan tentang eksekusi dari subruti tersebut. Jika suatu program menggunakan versi pertama. Akan tetapi. Apa contoh kegunaan tumpukan dalam keadaan sehari-hari? Misalnya. . catatan aktivasi (activation record) dibuat untuk subrutin tersebut. misalnya parameter dan variabel lokalnya. Dan sebetulnya TDA harusnya memberikan spesifikasi apa yang harus dilakukan jika program mencoba mengambil item dari tumpukan kosong. misalnya subrutin tersebut memanggil subrutin kedua. Bagaimana caranya? Yaitu dengan menggunakan tumpukan. lihat apa yang terjadi jika suatu rutin memanggil subrutin. maka kita bisa menggantinya dengan versi kedua tanpa mengubah isi program lain. ada satu kasus di mana kedua kelas akan berbeda. Ini yang sering dilupakan ketika seseorang membuat spesifikasi untuk interface. dan akan diteruskan apabila subrutin yang dipanggil selesai dijalankan. Catatan ini akan dibuang ketika subrutin selesai dipanggil. yang akhirnya masalah lain akan muncul di kemudian hari. } public boolean isKosong() { // Kembalikan true jika tumpukan kosong // Kembalikan false jika ada satu atau lebih item di dalam tumpukan return (atas == 0). Komputer harus bisa melacak subrutin yang dihentikan. Setiap subrutin akan berhenti untuk sementara ketika subrutin berikutnya dipanggil. misalnya EmptyStackException di kedua versi. maka versi pertama akan melemparkan NullPointerException sedangkan versi kedua akan melemparkan ArrayIndexOutOfBoundsException. dan subrutin kedua memanggil subrutin ketiga. Rutin pertama akan dihentikan sementara ketika subrutin yang dipanggil dieksekusi. implementasi tumpukan (dalam bentuk array) bersifat private. Kedua versi kelas TumpukanInt bisa digunakan dalam suatu program.

Di sini operator "-" dilakukan pada dua nilai sebelumnya. yaitu "15" dan "12". Sekarang kita sampai pada operator "-". Item berikutnya adalah "+". Ekspresi matematika biasa seperti 2+(15-12)*17 disebut ekspresi infix. misalnya "2 + 2". kemudian menyimpannya lagi ke dalam tumpukan. maka 3 ada di atas 2 di dalam tumpukan. Sekarang misalnya kita akan menghitung ekspresi "2 15 12 . dan kita lakukan perhitungan 15 . Hasil dari 3 * 17. kita ambil 2 nilai dari dalam tumpukan. Nilai 3 ini kita simpan lagi ke dalam tumpukan. yaitu 53. Sekarang kita sampai pada akhir ekspresi. misalnya "2 2 +". Tanda * dilakukan pada dua nilai sebelumnya.12 yaitu 3. yaitu 51 dimasukkan kembali ke dalam tumpukan (di atas 2 yang masih ada di dalam tumpukan). operator berada di tengah nilai yang akan dihitung. Setelah nilai 3 dimasukkan ke dalam tumpukan.17 * +". Dan operator "+" dilakukan pada 2 dan "15 12 17 *". Aturan penghitungan hanya ditentukan berdasarkan urutannya saja. yaitu 53. tapi apa yang bisa kita lakukan dengan 2? Di sini kita belum tahu operatornya. yang akan mengambil 51 dan 2 dari dalam tumpukan. kita akan melihat nilai 15. Dalam ekspresi infix. Hasilnya akan persis sama dengan ekspresi infix awalnya. Dalam ekspresi postfix. Contoh lainnya. Kita telah menyimpan 2 nilai sebelumnya ke dalam tumpukan. Satu hal. dan semakin kecil jika subrutinsubrutin itu selesai dijalankan. ekspresi postfix tidak memerlukan tanda kurung atau aturan perhitungan (tanda kali harus dilakukan lebih dulu sebelum tambah misalnya).Jika subrutin ini memanggil subrutin lain. Sehingga algoritma yang menghitung ekspresi postfix dapat menjalankannya dengan lebih cepat dan tepat. Kita akan ingat nilai 2 ini untuk sementara. Kemudian nilai 12 juga dimasukkan ke dalam tumpukan di atas 15. dan selain itu kita juga belum tahu nilai lainnya. yaitu dengan mendorongnya ke dalam tumpukan. yaitu 15 dan 12. Ingat bahwa 15 dan 12 sudah diambil dari dalam tumpukan. Nilai yang kita temui pertama adalah 2. Nilai pada tumpukan itu adalah hasil perhitungan keseluruhan ekspresi. Untuk menghitung item berikutnya "*". Kita cukup mengambil nilainya dan melaporkan hasilnya. Item berikutnya adalah 17. operator ada di akhir nilai. menghitung hasilnya. yaitu "15 12 -" dan "17". Ekspresi 2+(15-12)*17" dapat ditulis dalam bentuk postfix menjadi "2 15 12 . Sekarang kita ambil 2 nilai tersebut dari dalam tumpukan. yaitu 3 dan 17. yang kita juga masukkan ke dalam tumpukan di atas nilai 2. maka catatan aktivasi dari subrutin kedua akan didorong ke dalam tumpukan. Berikutnya. . tumpukan digunakan untuk mengevaluasi ekspresi postfix (postfix expresssion). sehingga hanya nilai 2 yang ada di dalam tumpukan. di atas catatan aktivasi subrutin pertama. ekspresi postfix memiliki beberapa keuntungan. yang juga dimasukkan ke dalam tumpukan di atas nilai 3. Meskipun lebih mudah bagi manusia untuk melakukan perhitungan dengan ekspresi infix. Operasi ini dilakukan pada dua nilai sebelumnya. Tumpukan akan semakin besar jika semakin banyak subrutin yang dipanggil.17 * +" dari kiri ke kanan.

Ekspresi postfix sering digunakan secara internal oleh komputer. Ketika variabel ditemukan di dalam ekspresi. Misalnya. Algoritma ini bisa diperluas untuk menangani variabel dan konstanta. Misalnya. Ini akan dideteksi ketika 2 masih ada di dalam tumpukan di akhir algoritma. di mana tidak cukup operator untuk menghitung semua nilai. tidak cukup nilai untuk menghitung operasi "*". Ini akan dideteksi oleh algoritma ketika mencoba mengambil nilai kedua dari dalam tumpukan. isi variabel ini didorong ke dalam tumpukan. Banyaknya nilai yang diambil dari dalam tumpukan bisa disesuaikan dengan berapa banyak nilai yang dibutuhkan. Dan sebenarnya.Algoritma untuk melakukan perhitungan ekspresi postfix adalah sebagai berikut : Mulai dengan tumpukan kosong untuk setiap item di dalam ekspresi: jika item berupa bilangan: Dorong item ke dalam tumpukan jika item berupa operator Ambil dua nilai dari tumpukan // bisa terjadi kesalahan Lakukan perhitungan dua nilai dengan operator tersebut Dorong hasil perhitungan ke dalam tumpukan else Ada kesalahan dalam ekspresi Ambil nilai dari tumpukan Jika tumpukan tidak kosong: Ada kesalahan dalam ekspresi else: Nilai terakhir adalah hasil perhitungan Kesalahan ekspresi dapat dideteksi dengan mudah. Kesalahan lain bisa juga muncul ketika menghitung ekspresi "2 3 4 +". yang menggunakan tumpukan untuk melakukan perhitungan yang telah kita diskusikan. misalnya "-x" hanya membutuhkan satu nilai. . mesin virtual Java adalah "mesin tumpukan". dalam ekspresi "2 3 + *". operator "-" sebagai operator negasi. karena pada saat itu tumpukan sudah kosong. Algoritma ini juga bisa dikembangkan untuk operator yang membutuhkan kurang atau lebih dari dua operator.

Antrian memiliki dua ujung. Kita juga membutuhkan metode instansi untuk menguji apakah antrian kosong atau tidak: void masul(int N) int keluar() // Tambah N di belakang antrian // Keluarkan antrian dari depan dan kembalikan isinya // Kembalikan true jika antrian kosong boolean isKosong() . Item selalu dimasukkan dari belakang antrian.Antrian Antrian (queue) adalah struktur data mirip dengan tumpukan. yaitu terdiri dari item dalam urutan tertentu. Untuk antrian int. Antrian bisa menampung item dengan jenis apa saja. Operasi memasukkan dan mengeluarkan item dari dalam antrian disebut "masuk" dan "keluar" (dalam bahasa Inggris disebut enqueue dan dequeue). Mirip seperti antrian pada kasir atau pada customer service di bank misalnya. operasi masuk dan keluar dapat diimplementasikan sebagai metode instansi dalam kelas "AntrianInt". Suatu item yang ditambahkan di belakang antrian tidak bisa dihapus sebelum item di depannya dihapus. dan selalu dikeluarkan dari depan antrian. Customer akan dilayani dalam urutan ketika mereka datang. yang disebut ujung depan dan ujung belakang.

// Menunjuk ke simpul akhir pada antrian void masuk( int N ) { // Menambahkan N ke akhir antrian Simpul buntutBaru = new Simpul(). sehingga akan kita abaikan dalam diskusi kita. if (kepala == null) { // Antrian kosong. Kita harus selalu ingat untuk terus mengupdate isi variabel ini setiap kali simpul baru ditambahkan ke akhir list. // Pointer ini akan menunjuk ke simpul terakhir buntut = kepala. } // Menunjuk ke simpul pertama pada antrian // Jika antrian kosong. di mana buntut adalah pointer ke simpul terakhir dari list. buntut. Jika kepala adalah pointer ke simpul pertama. maka kita bisa mendapat pointer ke simpul terakhir dengan menggunakan : Simpul buntut. } // Di sini. } . Akan tetapi implementasi yang efisien dalam bentuk array sedikit lebih sulit.Antrian bisa diimplementasikan dalam bentuk list berantai atau array. private Simpul buntut = null.".item = N. kita akan menyimpan pointer ke akhir simpul sebagai variabel instansi. // Simpul baru untuk menampung item baru buntutBaru. // Mulai dari simpul pertama while (buntut. Dengan alasan efisiensi. Simpul berikut.berikut. Dengan pengetahuan di atas.berikut = simpulBaru. maka kepala berisi null private Simpul kepala = null.berikut berisi null. tentunya akan sangat tidak efisien jika kita harus melakukan perulangan terus menerus setiap kali kita memasukkan item baru ke dalam antrian. kita bisa membuat kelas "AntrianInt" dengan mudah sebagai berikut : public class AntrianInt { private static class Simpul { // Objek bertipe Simpul berisi item dalam bentuk // list berantai int item. Sehingga // kepala dan buntut sama-sama menunjuk ke simpulBaru kepala = buntutBaru. Untuk mengeluarkan item dari depan antrian. Kita bisa menggunakan perintah seperti "buntut. artinya buntut adalah // simpul terakhir di dalam list Akan tetapi. kita harus mengeset pointer di akhir simpul untuk menunjuk ke simpul baru yang berisi item yang akan kita tambahkan. Unutk memasukkan item ke dalam antrian. item bertama adalah item di depan antrian.berikut != null) { buntut = buntut. kita dapat lakukan seperti mengambil item dari atas tumpukan. Dalam implementas dalam bentuk list berantai. Belakang antrian adalah akhir dari list. buntut = buntutBaru. sehingga simpulBaru menjadi // satu-satunya simpul di dalam list.

else { // Simpul baru menjadi buntut antrian // (kepala tidak berpengaruh apa-apa) buntut. Di lain pihak. akan tetapi banyak item bisa menunggu untuk diproses. memiliki antrian di dalamnya yang berisi permintaan sambungan yang diterima akan tetapi belum dilayani. Metode accept() pada kelas ServerSocket menerima permintaan sambungan berikutnya dari depan antrian ini. Item yang bisa keluar dari tumpukan adalah item terkakhir yang dimasukkan. thread ini ditambahkan ke dalam antrian. tumpukan adalah antrian yang tidak adil). } } int keluar() { // Keluarkan item dari kepala antrian // Bisa melempar NullPointerException. Seperti antrian. kepala = kepala. Terakhir Masuk Pertama Keluar). diolah oleh CPU. Mungkin saja terjadi beberapa event diterima ketika satu event sedang diproses. Simpul yang telah dihapus adalah // kepala sekaligus buntut. atau Pertama Masuk Pertama Keluar). } boolean isKosong() { // Kembalikan true jika antrian kosong return (kepala == null). tumpukan juga bisa digunakan untuk menampung item yang sedang menunggu untuk diproses (walaupun dalam aplikasi di mana antrian biasa digunakan. Program akan menghapus item dari antrian item dan mengolahnya satu per satu. buntut = buntutBaru. Isi buntut dengan null. Antrian disebut mengikuti kebijakan FIFO (First In First Out. pertama datang dan pertama dilayani. tumpukan mengikuti prinsip LIFO (Last In First Out. buntut = null. Ketika thread baru dimulai. } } // akhir kelas AntrianInt Antrian digunakan dalam komputer (dan juga dalam kehidupan nyata) ketika hanya satu item yang bisa diproses pada suatu saat. dan kemudian -.berikut = buntutBaru. } return itemPertama. akan tetapi event akan diolah berdasarkan urutan kedatangannya • ServerSocket.item.berikut. thread yang ingin diolah dalam CPU disimpan di dalam antrian. // Sekarang item kedua menjadi kepala if (kepala == null) { // Sekarang antrian kosong.jika belum selesai -. Atau dalam bahasa awam. Thread akan dihapus dari depan antrian. misalnya : • Dalam Java program yang memiliki banyak threads.diletakkan kembali di belakang antrian untuk menunggu giliran berikutnya. . • Event seperti ketikan tombol dan klik mouse disimpan dalam antrian yang disebut "antrian event". int itemPertama = kepala. karena simpul ini adalah satu-satunya // yang ada di dalam antrian.

Pohon Biner Kita telah melihat di beberapa bagian sebelumnya bagaimana objek bisa dikaitkan satu sama lain menjadi list berantai. dan simpul 4 dan 5 adalah anak dari simpul 2. kita bisa membuat struktur data yang lebih kompleks dari list berantai. yang biasa disebut kiri dan kanan. Simpul ini disebut simpul akar (root). tentunya simpul pada pohon memiliki data yang bisa bertipe apa saja. pohon biner integer bisa dibuat dalam bentuk : class SimpulPohon { int item. Dalam bagian ini kita akan melihat salah satu struktur dasar dan paling berguna: pohon biner (binary tree). Selain itu. simpul 3 adalah induk dari simpul 6. Simpul yang menunjuk pada simul lain disebut induk (parent). Ketika suatu objek memiliki 2 pointer ke objek dengan tipe yang sama. Tidak semua struktur yang terdiri dari simpul pohon merupakan pohon biner. Pohon biner harus memiliki sifat : • Harus ada satu simpul di dalam pohon yang tidak memiliki induk. • Simpul lain harus memiliki hanya satu induk . // Pointer ke cabang sebelah kiri SimpulPohon kanan. Misalnya. // Data pada simpul ini SimpulPohon kiri. // Pointer ke cabang sebelah kanan } Pointer kiri dan kanan dalam SimpulPohon bisa beriis null atau menunjuk pada objek lain dengan tipe SimpulPohon. Setiap objek dalam pohon biner memiliki dua pointer. sedangkan yang ditunjuk disebut anak (child). Dalam gambar di atas.

Lihat simpul tersebut beserta seluruh simpul turunannya (yaitu anak. 4. Ini adalah definisi rekursif. Simpul-simpul ini juga membentuk pohon biner. mari kita lihat bagaimana mencetak isi item di dalam pohon biner. Simpul daun dapat dikenali karena kedua pointer kiri dan kanannya berisi null. atau bisa terdiri dari akar dan dua pohon cabang. Dalam ilustrasi suatu pohon biner. artinya tidak boleh ada rantai pointer yang dimulai dari satu simpul dan berakhir di simpul yang sama. kita mungkin bisa membuat algoritma untuk menghitung simpul. Ini adalah jumlah simpul di dalam pohon. // Pohon kosong. maka banyaknya simpul adalah nol. yang disebut pohon cabang (subtree) dari pohon awalnya. static // // // void preorderCetak( SimpulPohon akar ) { Cetak semua item di dalam pohon yang ditunjuk oleh akar. biasanya simpul akar terletak di atas dan simpul daun terletak di bawah -. kita tidak melakukan apa-apa. Jika pohon kosong. Ini bukan hal sepele. Suatu pohon bisa kosong. return hitung. seperti pohon. // Mulai dengan ) { suatu pohon ada simpul di dalamnya menghitung akarnya // Tambahkan dengan simpul dari pohon cabang sebelah kiri jumlah += hitungSimpul(akar. simpul 2. Jika pohon tidak kosong. Simpul yang tidak memiliki anak disebut simpul daun (leaf). bagaimana melacak simpul mana yang belum dihitung. termasuk akarnya ( akar == null ) return 0. Salah satu atau kedua pohon cabang bisa kosong. Hal yang sama. Kemudian kita bisa menggunakan rekursi untuk menghitung jumlah simpul pada masing-masing pohon cabang. Pohon cabang ini disebut pohon cabang sebelah kiri dari simpul akarnya. Dengan rekursi.Tidak boleh ada perulangan dalam pohon biner. dan seterusnya). yang merupakan cikal bakal nama pohon biner ini. kita bisa melihat cabang-cabang.tidak sama seperti pohon sungguhan. algoritmanya akan jauh lebih mudah. Jadi tidak heran apabila kita menerapkan subrutin rekursif untuk mengolah struktur data pohon. Inti permasalahannya adalah. (Ini merupakan kasus dasar dari rekursi). Dan mungkin kita tidak mungkin menyelesaikannya tanpa menggunakan tumpukan atau antrian. Berikut ini adalah subrutin untuk mencetak semua item dalam satu baris cetakan. tidak else { int jumlah = 1. Item pada akar dicetak dahulu. // Kembalikan jumlahnya } } // akhir hitungSimpul() Juga. Jika pohon kosong. Mari kita lihat bagaimana caranya menghitung banyaknya simpul di dalam pohon biner. kemudian item di sebelah kiri dan baru item di pohon cabang sebelah kanan . Cetak item pada akarnya. simpul 3 dan 6 adalah pohon cabang sebelah kanan dari simpul akarnya. Jumlahkan hasil dari kedua cabang. // Tambahkan dengan simpul dari pohon cabang sebelah kanan jumlah += hitungSimpul(akar.kiri). anak dari anaknya. Misalnya. dan gunakan rekursi untuk mencetak item di dalam pohon cabangnya. mari kita lihat suatu simpul pada pohon biner. Misalnya. Dalam Java bisa kita tuliskan sebagai : • static // // if int hitungSimpul( SimpulPohon akar Hitung berapa simpul yang dimiliki biner. Sebagai latihan. dan 5 membentuk pohon cabang. maka mungkin ia berisi akar dan dua pohon cabangnya. kemudian tambah satu simpul akarnya.kanan). Akan tetapi. pada gambar di atas.

item + " " ). kemudian pohon cabang sebelah kiri ditelusuri. di mana : preorderCetak mencetak: postorderCetak mencetak: inorderCetak mencetak: 1 4 4 2 5 2 4 2 5 5 6 1 3 3 3 6 1 6 Dalam preorderCetak misalnya. // Print item akar preorderCetak( akar. kita tidak melakukan apa-apa. akarnya 3 akan dicetak sebelum 6.kanan ). Akan tetapi list berantai seperti ini bisa bekerja untuk jumlah . dan baru simpul akarnya ( akar != null ) { // (Jika null.kiri ).) System.kanan ). Urutan item ketika dicetak akan berbeda. kemudian kanan. cabang kiri ditelusuri. dan kemudian cabang kanan. yaitu 1. Akan tetapi urutan preorder juga dilakukan untuk setiap pohon cabangnya. // Print item di pohon cabang kiri postorderCetak( akar. Sedangkan untuk cabang sebelah kanan. Cabang pohon sebelah kiri dicetak dahulu. // Print item di pohon cabang kiri preorderCetak( akar. Dalam penelusuran preorder. baru kemudian simpul akar.out. // Print item di pohon cabang kiri System. Simpul akar pada pohon cabang sebelah kiri. // Print item akar inorderCetak( akar. Dan dalam penelusuran inorder.) postorderCetak( akar. Subrutin yang mencetak postorder dan inorder berbeda dengan preorder dalam urutan pencetakannya di layar : static // // // if void postorderCetak( SimpulPohon akar ) { Cetak semua item di dalam pohon yang ditunjuk oleh akar.print( akar.if ( akar != null ) { // (Jika null.) inorderCetak( akar. baru pohon cabang sebelah kanan ( akar != null ) { // (Jika null. Penelusuran preorder dilakukan pada semua cabang pohon.print( akar. Urutan penelusuran yang lainnya bisa dianalisis dengan cara yang sama.kiri ).print( akar. simpul akan diproses terlebih dahulu. // Print items di pohon cabang kanan } } // akhir preorderCetak() Rutin ini disebut "preorderCetak" karena ia menelusuri pohon secara preorder. Cabang pohon cabang sebelah kiri dicetak dahulu. yaitu 2. dicetak terlebih dahulu sebelum pohon cabangnya 4 dan 5. dan kemudian cabang sebelah kanan. // Print items di pohon cabang kanan System. kita tidak melakukan apa-apa. dicetak paling awal.out. kemudian cabang kanan. // Print item akar } } // akhir postorderCetak() static // // // if void inorderCetak( SimpulPohon akar ) { Cetak semua item di dalam pohon yang ditunjuk oleh akar. Pohon Pengurutan Biner Pada bagian sebelumnya kita membahas tentang list berantai dari string. cabang kiri dikunjungi dahulu.out. kemudian akar. Dalam penelusuran postorder. kita tidak melakukan apa-apa.item + " " ). // Print items di pohon cabang kanan } } // akhir inorderCetak() Subrutin ini bisa dijalankan pada pohon biner yang diilustrasikan di awal bagian ini.kiri ). kemudian simpul akarnya.item + " " ). di mana string dijaga agar tetap dalam urutan menaik. itam pada akar pohon.kanan ).

sehingga pencarian dan penyisipan bisa dilakukan dengan mudah. Penelusuran inorder menjamin bahwa semua item di cabang kiri pohon dari elemen "judy" akan dicetak sebelum "judy". karena pencarian biner bisa digunakan. kita harus mencari dahulu posisi yang tepat di mana item akan disisipkan. item pada simpul tersebut lebih besar dari semua item di cabang kiri pohon • Dan simpul tersebut. sedangkan pointer yang tidak null dilambangkan dengan tanda panah) • Pohon pencarian biner memiliki sifat penting berikut : Penelusuran inorder akan mengolah item dalam urutan menaik. kita harus melihat paling tidak separuh dari seluruh list. maka pencariannya bisa dilakukan lebih cepat. Misalnya. Untuk jumlah item yang sangat banyak. Ketika kita menambahkan item ke dalam list.yang tidak terlalu banyak. Karena sifat pohon biner yang mengharuskan item di cabang kiri . lebih besar atau sama dengan semua item di cabang kanan pohon Berikut ini adalah contoh pohon pengurutan biner yang memiliki item bertipe String. Pohon pencarian biner adalah pohon biner yang memiliki sifat : Untuk setiap simpul pada pohon. Jika string list diimplentasikan dalam bentuk array terurut. karena kita harus memindahkan paling tidak setengah isi array untuk memberi tempat untuk item baru yang akan disisipkan. Untuk melakukan pencarian. Akan tetapi untuk menyisipkan item ke dalam array terurut juga tidak efisien. list berantai kurang efisien. Pohon biner ini disebut pohon pencarian biner. dan semua item di cabang kanan pohon akan dicetak setelah "judy". Pohon biner bisa digunakan untuk menyimpan string list terurut (atau item jenis lain). penelusuran inorder digunakan untuk mencetak isi pohon di atas dalam urutan alfabet. (Dalam gambar ini pointer berisi null tidak digambarkan.

Jika isinya sama. class SimpulPohon { // Objek SimpulPohon adalah satu simpul pada // pohon biner string String item. Untuk semua kasus. SimpulPohon kanan. Pertama. besar kemungkinan pohon tersebut akan menjadi seimbang. Dalam pencarian dalam pohon pencarian biner. kita bisa menggunakan prosedur yang sama di setiap cabang pohon. Bagaimana dengan memasukkan item baru ke dalam pohon. Jika item yang kita cari kurang dari item pada simpul akar. buat simpul baru dan tempelkan simpul baru di tempat tersebut. maka akan semakin banyak elemen yang kita buang. Misalnya kita ingin mencari item di dalam pohon pencari biner. maka kita selesai. Demikian juga jika item yang kita cari lebih besar dari item pada simpul akar. Pencarian dan penyisipan item adalah operasi yang efisien pada pohon pencarian biner. maka keluarannya akan sama dengan mengurutkan isi pohon secara alfabet dalam urutan menaik. Mula-mula cari di posisi mana item tersebut akan dimasukkan. // Pointer ke cabang kanan SimpulPohon(String str) { . // Data pada simpul ini // Pointer ke cabang kiri SimpulPohon kiri. Simpul pada pohon biner diekspresikan dalam kelas SimpulPohon berikut ini. akan tetapi jika pohon ini dibuat secara acak. kita harus mencari ke sebelah kiri pohon -. Tidak semua pohon biner akan menjadi pohon seimbang.pohon sebelah kanan bisa diabaikan karena isinya hanya item yang lebih besar dari simpul akarnya. maka kita akan mencari di sebelah kanan pohon. beserta konstruktor untuk membuat simpul baru lebih mudah.lebih kecil dari item pada simpul. Jika posisinya ditemukan. bandingkan item dengan isi simpul akarnya. Mari kita lihat bagaimana mengimplementasikan pohon pencarian biner. setiap pengujian yang kita lakukan akan membuang sebagian cabang pohon. dan dengan demikian pencarian akan dilakukan dengan lebih cepat. Jika pohon tersebut dalam keadaan seimbang. asalkan pohon tersebut berada dalam kondisi seimbang (balanced). Ini mirip sekali dengan algoritma pencarian biner pada bagian sebelumnya. Suatu pohon biner berada dalam kondisi seimbang jika jumlah simpul pada cabang kanan sama dengan jumlah simpul pada cabang kiri.

item ).item) ) { // Item ini ditemukan di simpul akar return true. String item ) { // Kembalikan true jika item ditemukan dalam pohon if ( simpul == null ) { // Pohon kosong. static boolean pohonBerisi( SimpulPohon simpul. maka mungkin ada di // cabang kiri pohon. Membuat simpul berisi str item = str. akar berisi null static SimpulPohon akar. jadi sudah pasti tidak ada item ini // di dalamnya return false. } else if ( item.compareTo(simpul. Kembalikan hasil pencarian di // cabang kiri pohon return pohonBerisi( simpul.kiri. } } // akhir kelas SimpulPohon Variabel statik dengan tipe SimpulPohon menunjuk pada pohon pencarian biner: // Pointer ke simpul akar pohon // Ketika pohon kosong. Subrutin rekursif bernama pohonBerisi digunakan untuk mencari item di dalam pohon.equals(simpul.item) < 0 ) { // Jika item lebih kecil dari simpul. } .// Konstruktor. Subruin berikut melakukan pencarian pada pohon biner seperti didiskusikan di atas. } else if ( item.

String item ) { // Kembalikan true jika item ada di dalam pohon biner.item) ) { // Kita sudah menemukan item return true. Perlu dicatat bahwa rekursi bukan sesuatu yang penting dalam mengimplementasikan subrutin ini. sehingga implementasinya menjadi : static boolean pohonBerisiNR( SimpulPohon akar. dan item belum // ditemukan return false.equals(pointer.compareTo(pointer. // Pointer untuk menelusuri pohon pointer = akar. Kita bisa menggunakan perulangan while. SimpulPohon pointer.kanan. } else if ( item. Kembalikan hasil // pencarian di cabang kanan pohon return pohonBerisi( simpul. } } // akhir pohonBerisi() Ketika subrutin ini dipanggil.else { // Jika item sama atau lebih besar dari simpul. } else if ( item. item ).item) < 0 ) { // Mulai di akar simpul . maka // mungkin ada di cabang kanan pohon. Algoritma pohon pencarian biner yang tidak rekursif mengikuti aturan berikut : Turun ke bawah hingga kita menemukan item atau hingga mencapai null. parameter pertama adalah variabel anggota statik akar yang menunjuk pada akar seluruh pohonh pencarian biner. while (true) { if (pointer == null) { // Kita sudah sampai pada akhir pohon.

kiri. } } // akhir while } // akhir pohonBerisiNR(). (Catatan kita tidak bisa menggunakan // akar sebagai parameter.) if ( akar == null ) { // Jika pohon kosong.// Jika item lebih kecil. Perbedaan antara mencari dan menyisipkan item adalah kita harus berhati-hati untuk tidak jatuh dari pohon. set akar ke simpul baru . akar = new simpulPohon( itemBaru ).kanan. berarti akar tidak bisa diberikan sebagai parameter subrutin. kemungkinan ada di cabang kanan // Teruskan penelusuran di cabang kanan pohon pointer = pointer. maka akar menunjuk pada simpul baru. di situlah kita menempatkan simpul baru kita. Akan tetapi. Subrutin untuk menyisipkan item baru ke dalam pohon mirip dengan rutin pencari non-rekursif di atas. kemungkinan ada di cabang kiri // Teruskan penelusuran di cabang kiri pohon pointer = pointer. static void sisipPohon(String itemBaru) { // Tambahkan item ke dalam pohon pencarian biner. ARtinya. akan tetapi cara lebih mudah adalah menggunakan rutin penyisipan non-rekursif yang mengakses variabel anggota akar secara langsung. Selain itu rutin penyisipan harus bisa menguji apakah pohon kosong atau tidak. karena kita tidak bisa mengubah nilai yang disimpan dalam parameter aktual. Jika kita sampai pada tempat kosong. karena kita harus mengubah isi // variabel ini. (Ini bisa dilakukan dalam bahasa pemrograman lain). di mana // variabel "akar" berisi. Jika pohon kosong. kita harus selesai melakukan pencarian sebelum pointer bernilai null karena mencapai akhir pohon. Ada cari lainnya. } else { // Jika item lebih besar.

Jika tidak turun satu tingkat lagi ke kiri if ( pointer.// yang berisi itemBaru akar = new SimpulPohon( itemBaru ). Jika tidak turun satu tingkat lagi ke kanan if ( pointer.kiri maka simpul baru // bisa ditambah di sini. } else { // Karena itemBaru lebih besar dari item dalam pohon // maka ia harus berada di cabang kanan pohon.item) < 0 ) { // Karena itemBaru kurang dari item dalam pohon // maka ia harus berada di cabang kiri pohon. // Mulai dari akar while (true) { if ( newItem.compareTo(pointer.kanan == null ) { pointer.kiri = new SimpulPohon( itemBaru ). .kanan maka simpul baru // bisa ditambah di sini.kanan = new SimpulPohon( itemBaru ). // Jika ada ruang kosong di pointer. // itemBaru sudah ditambahkan ke dalam pohon } else pointer = pointer. } SimpulPohon pointer. return.kiri.kiri == null ) { pointer. // Jika ada ruang kosong di pointer. return. // Untuk menelusuri pohon pointer = akar.

Di bagian ini kita akan melihat bagaimana Java menyelesaikan masalah ini.kanan. Akan tetapi kode array dinamis untuk double. String. Sayangnya. bukannya membuat sesuatu yang lebih inovatif dan kreatif.Pemrograman Generik dan Kelas Koleksi Bagaimana caranya menghindari "reinventing the wheel". // itemBaru sudah ditambahkan ke dalam pohon } else pointer = pointer. algoritma dan data stuktur ini juga diprogram dan diprogram ulang oleh profesional komputer. dan diprogram ulang oleh mahasiswa ilmu komputer dalam beberapa generasi. seharusnya tidak perlu lagi membuat data struktur ini dari awal. • • • • • • Pemrograman Generik Pemrograman Generik pada Java List Set (Himpunan) Kelas Map Tabel Hash Pemrograman Generik Pemrograman generik adalah penulisan kode yang bisa digunakan oleh berbagai macam tipe data. Kita telah menemukan istilahnya pada bagian sebelumnya tentang array dinamis integer. Mereka menghabiskan waktu yang tidak perlu untuk memrogram ulang sesuatu yang sudah ada.return. Struktur data ini sudah banyak dimengerti dan diprogram ribuan kali sebelumnya. seperti yang sudah dibahas pada bab sebelumnya telah dipelajari. Programmer yang perlu menggunakan list atau pohon biner. Akan sangat tidak nyaman apabila kita harus mengkopi kodenya berulang-ulang untuk tipe data yang berbeda-beda. diprogram. Ini adalah kesempatan belajar yang sangat baik. atau membuat kembali sesuatu yang sudah ditemukan? Banyak struktur data dan algoritma. } } // akhir while } // akhir sisipPohon() Bab IX . Masalahnya adalah bagaimana agar struktur data yang tangguh tersedia dan siap digunakan oleh programmer. . Kode yang ditulis di sana untuk array dinamis integer hanya bisa bekerja untuk tipe data int. atau tipe data lainnya hampir sama.

awt. variabel pada Smalltalk tidak memiliki tipe. Solusi yang disediakan Java memiliki banyak fitur bagus. kita harus tahu bahwa beberapa kelas di dalam java. Misalnya. Parameter juga tidak memiliki tipe. Ini adalah contoh pemrograman generik : kode untuk kelas ArrayList cukup ditulis satu kali. semua nilai adalah objek. Meskipun tidak menjadi sepopuler Java atau C++. Kita akan lihat beberapa kelas lain dan bagaimana kelaskelas ini digunakan. Bahasa ini masih digunakan hingga kini. karena dua sifat bahasa ini. di semua program. Sudah pasti bukan yang terbaik. seperti integer atau string. Pada Smalltalk. Suatu nilai memiliki tipe. Demikian juga dengan struktur data bisa menampung data apa saja. string. seperti int atau double.) Kelas ArrayList hanyalah satu dari beberapa kelas dan interface yang merupakan pemrograman generik pada Java.Seperti disebutkan sebelumnya. akan tetapi bukan berarti cara ini adalah cara satu-satunya. Kelas ini pada dasarnya merupakan array dinamis dengan tipe Object. tetapi variabel tidak memiliki nilai. tidak bisa digunakan untuk tipe data primitif. (Sebelum kita menggunakan perintah import java. pada dasarnya semua pemorgraman adalah generik. Karena semua kelas merupakan kelas turunan dari Object. atau data apa saja. bahasa ini adalah sumber ide yang diadopsi banyak bahasa pemrograman. Adalah sesuatu hal yang tidak mudah untuk mendesain pustaka untuk pemrograman generik.util dan kita perlu menambahkan pernyataan import di awal program untuk bisa menggunakannya. Kedua. Java mencoba menyelesaikan masalah ini dengan membuat kelas ArrayList. akan tetapi dalam konteks desain Java secara keseluruhan. operasi ini dilakukan dengan memanggil metode pada .util. Pertama. Pemrograman Generik pada Bahasa Pemrograman Lain Pemrograman Generik pada Smalltalk Smalltalk adalah salah satu bahasa pemrograman berorientasi objek pertama. tetapi bisa digunakan untuk objek dengan tipe data yang berbeda-beda (akan tetapi. dan semua operasi pada objek dilakukan dengan metode dalam kelas. Hal ini juga berlaku bahkan untuk tipe data primitif seperti integer.List adalah kelas yang bernama sama dengan paket yang berbeda).List dan java.*. Suatu variabel bisa menampung jenis data apa saja. sehingga subrutin bisa digunakan pada parameter apa saja. Misalnya. mungkin akan lebih baik untuk melihat sekilas pemrograman generik di bahasa pemrograman lain. tanggal. kita bisa menggunakannya untuk integer. sekali kita mendefinisikan struktur data pohon biner pada Smalltalk. java. mungkin lebih cocok disebut optimal. maka objek yang bertipe kelas apapun bisa disimpan dalam ArrayList. Kita tidak perlu menulis kode baru untuk masingmasing tipe data.util. Untuk dapat memberikan gambaran seperti apa pemrograman generik secara umum.util memiliki nama yang sama pada pake lain. Semua kelas yang didiskusikan pada bagian ini merupakan bagian dari paket java. Ketika operator "+" digunakan untuk menjumlah integer.

kita bisa memiliki bahasa di mana struktur data dan algoritmanya akan bekerja untuk jenis tipe data apapun (yang masuk akal). Inilah yang merupakan pemrograman generik yang sesungguhnya. Sekali kita membuat struktur data yang bisa menampung tipe data apa saja. dan hanya bisa menampung tipe data itu saja. kompiler tidak bisa memastikannya. Ketika kita membuat kelas baru. bahkan lebih kuat dari Java. Pemrograman Generik pada C++ Tidak seperti Smalltalk. karena sintaks C++ mirip dengan Java : template<class TipeItem> . akan sulit untuk menjamin ia bisa menampung tipe data yang kita inginkan. yaitu jika operasi yang sesuai telah didefinisikan. Kebebasan pemrograman seperti ini akan memudahkan kita membuat program. Template ini bukan subrutin. akan tetapi akan lebih sulit untuk membuat program yang benar dan tangguh. Setiap variabel memiliki tipe. kita bisa membuat operator "+" sendiri kemudian kita bisa menjumlahkan dua objek dengan tipe kelas tersebut dengan menggunakan "a + b" seperti kita menjumlahkan angka seperti biasa. tapi juga bisa digunakan ke tipe data apapun yang mendefinisikan "+". Akan tetapi kita bisa mmebuat template subrutin. Akan tetapi. Kita lihat contoh berikutnya. tidak ada kelas yang merupakan kelas super dari semua kelas. yaitu yang disebut template. dan Anda mungkin bertanya-tanya kenapa tidak semua bahasa pemrograman bekerja seperti ini. kita tidak membuat subrutin pengurutan yang berbeda untuk setiap tipe data. Subtuin ini bisa digunakan untuk list integer. Demikian juga dengan subrutin yang menggunakan operator "<" untuk mengurutkan list juga bisa digunakan untuk list yang mengandung tipe data apapun yang memiliki definisi "<". Masalah ini akan muncul di saat program dijalankan ketika kita mencoba untuk menjalankan operasi tertentu pada suatu tipe data yang belum ada. Lebih Jauh. C++ adalah bahasa pemrograman dengan tipe kuat. Dalam C++. Mungkin ini terdengar sangat baik. Lebih khusus. Artinya. Jika kita ingin suatu subrutin mengurutkan tipe data apapun. Kita tidak perlu menulis subrutin pengurutan untuk masing-masing tipe data. C++ tidak memiliki sesuatu yang mirip dengan kelas Object pada Java. akan tetapi mirip seperti pabrik pembuat subrutin. C++ memiliki sistem pemrograman geneik yang canggih dan fleksibel.kelas integer. Sekarang misalnya kita membuat subrutin baru yang menggunakan operator "+" untuk menjumlahkan masing-masing item di dalam list. kemudian program akan crash. maka akan sangat sulit untuk menjamin bahwa subrutin ini hanya digunakan untuk data di mana operator "<" telah didefinisikan. Artinya pemrograman generik seperti pada Smalltalk tidak mungkin diterapkan. Artinya C++ tidak bisa menggunakan pemrograman generik seperti Java. Jika kedua fitur ini kita gabungkan.

maka kita bisa mendapatkan subrutin untuk mengurut array int. for (int j = 1. Ini yang sebenarnya dilakukan oleh compiler. Jika kita mengganti "TipeItem" dengan string. Jika kita menulis template untuk pohon biner.10)" di mana kartu adalah array objek bertipe Kartu. akan tetapi ini akan terjadi pada saat program dikompilasi bukan seperi Smalltalk di mana program akan crash pada saat dijalankan. pada semua isi template. maka kompiler akan menggunakan template dengan sukses. C++ juga memiliki template untuk membuat kelas. dan seterusnya -. Jika ">" tidak didefinisikan untuk kelas Kartu. maka kita bisa mendapatkan subrutin untuk mengurut array string.semua dari satu template. Jika program kita menyebut "urut(list. Jika kita sebut "urut(kartu. Jika kita menghapus baris pertama. Jika operator ini didefinisikan untuk nilai bertipe Kartu. } } Dalam kode di atas. i > 0. j++) if ( A[j] > A[posisi_maks] ) posisi_maks = j. kita bisa menggantinya dengan tipe apapun. A[banyak] = A[posisi_maks]. pohon biner string. i--) { int posisi_maks = 0. pohon biner tanggal.10)" di mana list adalah array int. j <= banyak. kita bisa menggunakan template itu untuk membuat kelas pohon biner int. kita mendefinisikan template subrutin. (Meskipun kita tulis seperti "class TipeItem". maka kompiler akan membuat subrutin untuk mengurutkan array Kartu. TipeItem temp = A[banyak]. dan mengganti kata "TipeItem" dengan "int". A[posisi_maks] = temp.void urut( TipeItem A[]. termasuk tipe primitif). Versi paling baru C++ memiliki template bawaan yang cukup komplit yang disebut dengan Pustaka Template Standar . Template di atas menggunakan operator ">" untuk membandingkan nilai. yaitu template<class TipeItem>". maka kompiler akan gagal. ke dalam urutan menaik // Algoritma yang digunakan adalah pengurutan pilihan for (int i = banyak-1. int banyak ) { // Urut banyak item dalam array A. maka kompiler menggunakan template ini untuk membuat subrutin untuk mengurut array int.

subrutin dapat dipanggil dengan parameter bertipe apapun. Akan tetapi ini juga fitur paling menarik dari C++ Pemrograman Generik pada Java Seperti pada C++. tetap saja ini tidak menghambat Java untuk digunakan secara luas.(Standard Template Library atau STL). parameter suatu subrutin harus bertipe tertentu. Seperti telah dijelaskan sebelumnya. dan pendekatan C++ tidak tersedia pada Java. dan karenanya tidak bisa disimpan dalam tipe data generik. Kita akan lihat bagaimana Java menyelesaikan masalah ini. Pendekatan Smalltalk tidak bisa diterapkan pada Java kecuali untuk objek. Karena masalah seperti ini. akan tetapi subrutin hanya bisa menggunakan operasi pada kelas Object saja. Subrutin dengan parameter Object bisa digunakan untuk objek tipe apa saja. Koleksi kurang lebih mirip seperti kumpulan objek-objek. pemrograman generik pada Java lebih dekat dengan Smalltalk daripada C++. pemrograman generik pada Java berdasarkan pada kelas Object yang merupakan kelas super dari semua kelas. Akan tetapi. subrutin generik lebih bermasalah pada Java daripada Smalltalk atau C++. Lebih jauh. Hingga tingkat tertentu. jadi kita tidak bisa membuat algoritma pengurutan generik. • • • • • Koleksi dan Map Algoritma Generik Iterator Kesamaan dan Perbandingan Kelas Pembungkus Koleksi dan Map Struktur data generik pada Java dapat dibagi menjadi dua kategori : koleksi dan map. Dan sebenarnya. Pada Java. Akan tetapi. . Kita tidak perlu membuat template atau fitur pada bahasa pemrograman lain untuk mendukung pemrograman generik. ini membuat Java mirip dengan Smalltalk : Struktur data yang didesain untuk menampung Object bisa digunakan untuk menyimpan data kelas apapun. tidak ada cara untuk melakukan pemrograman generik dengan tipe data primitif pada Java. Pada Smalltak. beberapa orang menyatakan bahwa Java tidak mendukung pemrograman generik secara keseluruhan. STL sendiri cukup kompleks. tipe primitif. Beberapa orang lain tidak setuju. bukan objek pada Java. dan akan bekerja asalkan operator yang digunakan pada subrutin didefinisikan pada parameternya. Map menghubungkan objek di satu kumpulan dan objek di kumpulan lain seperti kamus yang menghubungkan definisi dengan kata atau buku telepon menghubungkan nama dan nomor telepon. Dan subrutin hanya bisa menggunakan operasi untuk tipe itu saja. Map mirip dengan apa yang kita sebut "list asosiasi" pada bagian sebelumnya. dan bahkan beberapa orang mengatakan sangat amat kompleks. dan sebenarnya hanya sedikit operasi pada kelas Object! Misalnya tidak ada operasi pembanding pada kelas Object. seperti integer. Tentunya. Java adalah bahasa bertipe kuat.

. dan "map" tidak menyatakan bagaimana data disimpan. Misalnyakol adalah objek yang mengimplementasi interface Collection. jika ada. list berantai. Lihat bahwa istilah "koleksi".isEmpty() -. item kedua. tapi tidak menjelaskan bagaimana struktur data dan operasinya diimplementasikan. Parameternya bisa berupa Collection apa saja. Tapi sebelum kita sampai pada bagian itu.remove(objek) -. List. Karena "koleksi" adalah konsep yang sangat umum. Kita akan lihat kelas list. 2. List adalah kumpulan objek di mana itemitemnya diatur secara berurutan. Mereka memiliki definisi operasi yang bisa dilakukan.mengembalikan nilai boolean jika objek ada dalam koleksi • kol. Untuk item di dalam list. Sebetulnya istilah-istilah ini dibuat pada Java bukan dalam bentuk kelas tapi dalam bentuk interface.containsAll(kol2) -. dan seterusnya. 1. Struktur data generik pada Java adalah tipe data abstrak (abstract data type).membuang objek dari dalam koleksi. Parameternya bisa berupa Object apa saja. Berikut ini adalah operasi yang bisa dilakukan.clear() -. Struktur data dan operasinya akan ditulis pada kelas yang mengimplementasikan interface tersebut.addAll(col2) -.. Interface Collection.mengembalikan nilai boolean jika semua objek dalam kol2 ada di dalam koleksi kol. "himpunan". • kol. sementara yang lain tidak. Himpunan (set) adalah kumpulan objek di mana hanya ada satu objek yang bisa ada di dalam suatu himpunan. set dan map pada bagian berikut. maka operasi yang bisa dilakukan oleh semua koleksi juga sesuatu yang sangat umum. . List bisa diimplementasikan dalam bentuk array. "list". kita akan melihat dahulu beberapa konsep tentang operasi umum yang tersedia pada semua koleksi. dan mengembalikan nilai boolean yang menyatakan apakah objek tersebut ada atau tidak di dalam koleksi • kol.size() -.mengembalikan boolean true jika koleksi kosong.contains(objek) -.mengembalikan int yang berisi banyaknya objek dalam suatu koleksi • kol. Set dan Map mendefinisikan operasi dasar dari struktur data tersebut. List memiliki item pertama. akan ada item yang ada di belakangnya. atau ukurannya sama dengan 0 • kol. kita mungkin tidak tahu bagaimana kelas tersebut diimplementasikan.menambah objek ke dalam koleksi. atau map yang menghubungkan elemen list dengan angka 0. kecuali item terakhir. • kol. • kol.add(objek) -. Algoritma Generik Interface Collection memiliki metode untuk melakukan beberapa operasi dasar pada koleksi.. kecuali kita melihat langsung pada kode sumbernya.menghapus semua objek dalam koleksi • kol. Bahkan ketika kita menggunakan kelas tersebut. Misalnya menambahkan objek ke dalam Set tidak berpengaruh apa-apa jika objek tersebut sudah ada di dalamnya.Ada dua jenis koleksi : list dan himpunan (set). Beberapa koleksi bisa berisi nilai null.menambahkan semua objek yang ada dalam koleksi kol2 ke dalam kol . dan bukan bagaimana data diatur dalam memori komputer.

Algoritma yang menggunakan iterator untuk menelusuri koleksi bisa dibuat generik. kita bisa menggunakan perulangan while dari item pertama hingga kita menemukan null. Bahkan untuk metode sesederhana size() bisa sangat berbeda dari satu jenis koleksi ke jenis koleksi lainnya.removeAll(kol2) -. Hanya akan mempertahankan objek yang ada pada kol2 • kol. Nilai yang dikembalikan bisa di-tipe cast ke dalam tipe array lain. Kita telah lihat sebelumnya bagaimana caranya untuk data struktur tertentu : Misalnya untuk array. sehingga menjalankan size() sama dengan mengambil nilai variabel instansi ini. Koleksi lain mungkin memiliki variabel instansi yang melacak jumlah item di dalam koleksi. Koleksi bisa dibuat dalam berbagai bentuk.menghapus semua objek pada kol yang tidak ada pada kol2. Meskipun suatu operasi didefinisikan untuk beberapa jenis koleksi. alangkah lebih baiknya untuk mengetahui seberapa efisien suatu operasi dilakukan untuk jenis koleksi tertentu. tidak peduli berapa banyak item yang ada di dalam koleksi. akan tetapi mungkin kita ingin membuat algoritma generik kita sendiri. maka (String[])kol. Misalnya. Meskipun mungkin legal untuk memanggil metode ini.kol. jika perlu. Untuk bisa melakukan ini secara generik. bagaimana kita bisa membuat metode generik yang berlaku untuk semua kenis koleksi? Masalah ini bisa diselesaikan dengan iterator. maka metode ini harus didefinisikan pada semua objek yang mengimplementasikan interface ini. Kita akan lihat lebih detail di bagian berikutnya. akan tetapi semua iterator digunakan dengan cara yang sama. Misalnya ukuran suatu Collection tidak bisa diganti setelah dibuat.toArray() akan mengembalikan array String yang berisi semua string di dalam koleksi. Ketika kita menggunakan koleksi. Artinya operasinya hanya dilakukan satu langkah saja. jika kita tahu bahwa semua item di dalam kol bertipe String. Kita harus bisa memilih koleksi yang cocok untuk masalah yang kita hadapi. Jenis pengecualiannya bernama UnsupportedOperationException. Akan tetapi ada masalah yang timbul. Untuk list berantai. tentunya unjuk kerjanya tidak sama untuk semua kelas. Konsep iterator mungkin agak aneh untuk seseorang yang baru menemui konsep pemrgoraman generik. Karena semua metode adalah turunan dari interface Collection. pengecualian akan dilemparkan ketika program dijalankan. akan tetapi Anda harus mengerti bahwa konsep ini bisa digunakan untuk menyelesaikan masalah sulit dengan cara yang anggun. Koleksi dengan jenis yang berbeda memiliki jenis iterator yang berbeda pula. Misalnya kita ingin membuat suatu subrutin yang mencetak setiap item di dalam koleksi. waktu pengolahan sebanding dengan jumlah item di dalam koleksi. .mengembalikan array bertipe Object[] yang isinya semua item di dalam koleksi. kita bisa menggunakan perulangan for dari item pertama hingga terakhir. Untuk beberapa jenis koleksi. Dengan keragaman bentuk ini dan bermacam-macam cara untuk menelusurinya.menghapus semua objek di kol yang ada pada kol2 • kol.retainAll(kol2) -.toArray() -. kita harus mencari akal bagaimana caranya untuk mengakses setiap item satu per satu. Ada juga masalah efisiensi. • Iterator Interface Collection mendefinisikan beberapa algoritma generik. karena teknik yang sama bisa digunakan untuk beragam jenis koleksi. Untuk pohon biner kita bisa menggunakan subrutin rekursif dengan penelusuran infix. Metode yang menambah atau membuang objek tidak bisa digunakan untuk koleksi jenis ini. Iterator adalah objek yang digunakan untuk menelusuri koleksi.

next() bertipe Object.iterator(): while ( iter.gambar(). Maka kita bisa membuat metode generik untuk menggambar semua gambar dalam koleksi BentukGeometri seperti : void gambarSemuaGambar( Collection koleksiGambar ) { // Kondisi Awal: Semua item dalam koleksiGambar tidak berisi null // dan bertipe kelas BentukGeometri Iterator iter = koleksiGambar. gbr.hasNext() -. kita menggunakan kelas BentukGeometri.next(). koleksi digunakan untuk menyimpan objek yang bertipe kelas tertentu. Nilai keluarannya bertipe Object.hasNext() ) { BentukGeometri gbr = (BentukGeometri)iter.hasNext() ) { Object item = iter. } } Koleksi bisa menampung objek tipe apa saja. Maka kita bisa menggunakan : • iter.iterator(). Ingat bahwa kita tidak bisa melihat suatu item tanpa memindahkan iterator ke item berikutnya. if (item == null) iter.next() -. Interface ini hanya memiliki 3 metode.iterator().jika kita gunakan perintah ini setelah memanggil iter. Jika iter merupakan variabel bertipe Iterator. Dalam situasi praktis.out.remove() Iterator iter = kol. Misalnya kol bertipe Collection.next(). • iter. Iterator didefinisikan oleh interface yang bernama Iterator. Akan melempar pengecualian UnsupportedOperationException jika koleksi tidak bisa menghapus item.iterator() mengembalikan iterator yang bisa digunakan untuk menelusuri koleksi tersebut. Misalnya kelas ini memiliki metode gambar() untuk menggambar suatu gambar. } . while ( iter. sehingga nilai keluaran iter.println(item).mengembalikan nilai boolean yang memberi tahu apakah ada item berikutnya yang bisa diproses. maka : • iter. Jika kol adalah suatu koleksi. subrutin berikut ini akan menghapus semua nilai null dari koleksi apapun (selama koleksi itu mengizinkan penghapusan elemen) : void removeNullValues( Collection coll ) { Iterator iter = kol. Misalnya. Kita harus mengetesnya sebelum memanggil iter. Bayangkan iterator seperti pointer generik yang dimulai dari awal koleksi dan bisa berpindah dari satu item ke item lain.next() -. Jika metode ini dipanggil apabila tidak ada item lagi yang tersisa. tidak ada yang bisa kita lakukan dengan variabel bertipe Object. Sekarang. Misalnya.mengembalikan item berikutnya. maka kol. Dengan menggunakan iterator.hasNext() ) { Object item = iter. kita bisa menulis kode untuk mencetak semua item dalam koleksi apapun.next(). } Bentuk yang sama bisa digunakan untuk pemrosesan jenis apapun.next(). ia akan melempar NoSuchElementException.remove(). maka ia akan menghapus item yang baru saja kita lihat. dan memindahkan iterator ke item berikutnya. kemudian objek dari koleksi itu di-tipe cast ke kelas tersebut sebelum digunakan. System.Interface Collection memiliki metode yang bisa digunakan untuk mengambil iterator dalam koleksi apapun. while ( iter.

Dua nilai String dianggap sama jika keduanya memiliki urutan karakter yang sama. int angka.next()" akan melempar pengecualian ClassCastException. Akan tetapi pada hampir semua kelas turunan Object. maka tipe-cast "(BentukGeometri)iter.equals(obj2) bernilai true. sehingga metode kesamaan bisa berjalan sesuai dengan yang kita inginkan. Teknik yang paling umum untuk menguji kesamaan (yaitu menggunakan operator ==) sering kali tidak bisa digunakan untuk objek. dua objek obj1 dan obj2 dianggap sama jika keduanya bernilai null atau jika keduanya bernilai tidak nul dan obj1. Misalnya kelas Kartu akan bekerja dengan benar jika digunakan dalam koleksi bisa dibuat seperti : public class Kartu { // Kelas untuk kartu mainan int lambang. Di dalam koleksi. membebanlebihkan equals() sehingga untuk str.remove(objek) mencari item dalam koleksi yang sama dengan objek. kita ingin supaya kesamaan berarti isi objeknya sama (bukan alamat memorinya). Jika kita menulis kelas sendiri. // Nomor 0 hingga 3 untuk lambangnya : // wajik. Kesamaan dan Perbandingan Diskusi kita tentang metode pada interface Collection sebelumnya mengasumsikan bahwa dua objek dianggap "sama". diamon. Dua nilai bertipe Date dianggap sama jika isinya adalah waktu yang sama. Jika hanya perlu ingat objek jenis apa yang kita simpan dalam koleksi kita. Dalam kelas Object. definisi ini tidak masuk akal. dan biasanya dibebanlebihkan (overload). obj1. keriting atau hati. Kelas Object memiliki metode bernilai boolean yaitu equals(Object) untuk menguji apakah satu objek berisi sama dengan objek lain. // Angka 1 hingga 13 . kesamaan bukan sesuatu yang mudah. Jika item ini ditemukan. dan hanya bisa memiliki "Koleksi Object". dalam prakteknya ini bukan masalah besar. Meskipun dalam Java kita tidak bisa memiliki "Koleksi Bentuk Geometri". Biasanya.} Kondisi awal dari metode tersebut menyatakan bahwa metode tersebut akan gagal apabila item di dalam koleksi tidak bertipe BentukGeometri. Kelas String misalnya. Akan tetapi.contains(objek) dan kol.equals(obj) bernilai sama jika urutan karakter obj sama dengan urutan karakter str. Persoalan di mana karakter tersebut disimpan di dalam memori tentunya tidak relevan. Operator == yang digunakan pada objek hanya membandingkan apakah objek tersebut memiliki alamat memori yang sama. kita mungkin ingin mendefinisikan metode equals() sendiri pada kelas tersebut.equals(obj2) didefinisikan sebagai obj1 == obj2. Misalnya metode kol.

.lang. metode tertentu harus dibuat untuk membandingkan objek. } else return false. Interface ini mendefinisikan satu metode. Objek yang akan dibandingkan harus mengimplementasikan interface java. Sebelum objek bisa diurutkan.lambang && angka == lain. // Type-cast obj ke Kartu if (lambang == lain.. Masalahnya.public boolean equals(Object obj) { if (obj == null || ! (obj instanceof Kartu) ) { // obj tidak sama dengan Kartu ini jika obj // tidak bertipe Kartu.angka) { // Kartu lain berlambang dan berangka sama dengan // kartu ini. artinya kedua kartu sama return true. } } . } else { Kartu lain = (Kartu)obj. Masalah yang sama akan muncul ketika item dalam koleksi akan diurutkan. tidak ada aturan "menaik" dalam objek. atau isinya null return false. yaitu : public int compareTo(Object obj) . // metode dan konstruktor lain } Tanpa metode equals() dalam kelas ini. metode contains() dan remove() dalam interface Collection tidak akan bekerja dengan baik untuk kelas Kartu.Comparable. Pengurutan artinya mengatur urutan item dalam aturan tertentu.

namaDepan) && namaBelakang. Misalnya : class NamaLengkap implements Comparable { // Melambangkan nama lengkap yang terdiri dari // nama depan dan nama belakang String namaDepan. namaBelakang. } else { NamaLengkap lain = (NamaLengkap)obj.compareTo(lain. Keluarannya bernilai positif jika obj1 lebih besar dari obj2 atau jika diurutkan dalam urutan menaik obj1 muncul setelah obj2. } } public void compareTo(Object obj) { NamaLengkap lain = (NamaLengkap)obj.compareTo(obj2) bernilai nol jika kedua objek berisi sama (atau jika obj1.equals(lain. // Menyebabkan error jika obj tidak bertipe NamaLengkap if ( namaBelakang. Keluarannya bernilai negatif jika obj1 lebih kecil dari obj2. Jika kita ingin membuat kelas sendiri dan ingin mengurut objek pada kelas itu. public boolean equals(Object obj) { if (obj == null || ! (obj instanceof NamaLengkap)) { return false. return namaDepan.equals(obj2) bernilai benar).namaBelakang).equals(lain.namaBelakang) < 0 ) { . atau jika diurutkan dalam urutan menaik obj1 akan muncul sebelum obj2.Nilai yang dikembalikan obj1. Kelas String mengimplementasikan interface Comparable dan memiliki metode compareTo dengan cara seperti di atas. kita juga harus mengimplementasikan objek itu dengan cara yang sama.

} } .compareTo(lain. tergantung apakah obj1 muncul lebih dulu.util. yaitu dengan membuat objek lain untuk melakukan perbandingan.. Komparator ini berfungsi untuk membandingkan objek yang tidak memiliki interface Comparable atau untuk melakukan metode pembanding yang berbeda untuk objek yang bertipe sama. ..Comparator yang memiliki metode : public int compare(Object obj1.namaBelakang) > 0 ) { // Jika namaBelakang lebih besar dari namaBelakang objek lain // maka NamaLengkap ini muncul setelah yang lain // Kembalikan nilai positif return 1.// Jika namaBelakang lebih kecil dari namaBelakang objek lain // maka NamaLengkap ini muncul sebelum yang lain // Kembalikan nilai negatif return -1. // metode dan konstruktor lain } Ada cara lain untuk membandingkan objek pada Java. atau positif. } if ( namaBelakang. Kita akan lihat bagaimana Comparable dan Comparator digunakan dalam koleksi dan map. Object obj2) Metode ini membandingkan dua objek dan mengembalikan nilai negatif. Objek tersebut harus mengimplementasikan java. } else { // Nama belakangnya sama. sama. sekarang bandingkan // nama depannya return namaDepan.compareTo(lain. atau setelah obj2.namaDepan). nol.

Kita akan bahas masalah ini sebelum kita beranjak pada bagian berikutnya. Misalnya.Integer berisi sebuah int saja. Objek Integer bisa digunakan untuk struktur data generik dan dalam situasi lain jika objek dibutuhkan. Jika bil variabel yang menunjuk pada objek bertipe Integer. Kita tidak bisa menyimpan integer pada struktur data generik yang didesain untuk menyimpan Object. setelah dibuat. Nilai di dalam objek bertipe Double bisa diambil dengan metode instansi doubleValue(). . Ada kelas pembungkus untuk semua tipe primitif. Artinya.lang. maka kita akan tahu berapa bilangan yang disimpan dalam objek ini dengan memanggil metode instansi bil.intValue(). yaitu lawan kata dari mutable atau dapat bermutasi).Kelas Pembungkus Seperti disebutkan sebelumnya. Semua objek dari tipe ini adalah objek immutable. Metode lain dalam kelas pembungkus adalah fungsi bantu untuk bekerja dengan tipe primitif. Objek yang bertipe java. kelas pembungkus mendefinisikan metode equals(Object) dan compareTo(Object) dengan benar. kita akan membuat kelas yang tidak berisi apa-apa kecuali sebuah integer : public class KontainerInt { public int nilai. Kelas pembungkus memiliki beberapa metode yang berguna. Kelas pembungkus untuk tipe double adalah java. Beberapa digunakan untuk mendukung pemrograman generik. Kita sebut objek Integer sebagai objek <span style="color: #ff0000. } Sebenarnya. Dalam kasus sederhana. kita tidak bisa mengubahnya. (Sama seperti objek bertipe String adalah objek immutable). Nilai int tersebut disimpan dalam variabel instansi private final dari objek Integer. misalnya Integer bil = new Integer(17).parseDouble(String). Fungsi ini digunakan untuk mengubah string seperti "42" atau "2. membuat objek Integer yang membungkus angka 17.">immutable</span> (objek yang tak mungkin berubah.Double.lang.parseInt(String) dan Double. kita temukan sebelumnya metode Integer. Kita tidak bisa mengganti angka tersebut. Java telah memiliki kelas seperti ini. Misalnya. tidak ada yang menghentikan kita untuk membuat objek yang hanya berisi integer dan menggunakan objek itu untuk ditempatkan pada struktur data. Nilai int bisa dimasukkan dalam konstruktor. Di lain pihak.3421213" ke dalam angka yang sesuai. Kelas ini disebut kelas pembungkus (wrapper) untuk int. pemrograman generik pada Java tidak berlaku untuk tipe primitif.

Metode remove(Object) dilakukan dengan mencari itemnya dahulu.List. array lebih efisien. terutama dari depan atau dari tengah list.util. ArrayList adalah urutan objek yang disimpan dalam bentuk array yang ukurannya bisa membesar jika item baru ditambahkan. isEmpty. Kita telah membahas keduanya sebelumnya (di sini dan di sini). tidak ada satupun struktur data list yang bisa melakukan semua operasi list secara efisien. yaitu dengan mengubah pointernya saja. Lalu kenapa kita memiliki 2 kelas? Mengapa bukan satu kelas List saja dengan satu jenis struktur data? Masalahnya. Interface List menambah beberapa metode untuk mengakses item pada list tergantung dari urutannya dalam list. 2. item harus digeser untuk membuat tempat kosong baru ditengah list.List Ada dua cara paling umum untuk membuat list : sebagai array dinamis dan sebagai list berantai. yang memiliki operasi yang sama untuk semua jenis list. Untuk operasi lainnya. Secara garis besar.. simpul bisa diputus di tengah-tengah untuk menambahkan item baru. Pada list berantai. . Tergantung daripada bagaimana list tersebut digunakan.LinkedList. Kedua kelas ini mengimplementasikan interface java. list berantai lebih efisien daripada array. Dalam array. remove(Object). operasi tersebut memerlukan waktu yang cukup besar. dan clear().size() . jika tidak maka pengecualian IndexOutOfBoundsException akan dilemparkan.util. Kelas ArrayList lebih efisien digunakan jika akses random (random access) dibutuhkan oleh aplikasi. add(Object).util. . Kedua list tersebut mendukung operasi list dasar.ArrayList dan java. Untuk operasi tertentu. hingga list.mengembalikan Object di posisi indeks dalam list. Semua list mengimplementasikan metode dalam Collection. Operasi yang bisa dilakukan dengan efisien oleh kedua kelas tersebut adalah mengurutkan dan menambah item di akhir list. Akses random maksudnya mengakses item ke-n di tengah-tengah list dan pindah dari satu item ke item lain yang letaknya mungkin berjauhan. metode-metode yang tersedia adalah : • list... kelas LinkedList lebih efisien untuk aplikasi di mana item-itemnya lebih sering ditambah atau dibuang dari dalam list. Sedangkan LinkedList adalah urutan objek yang disimpan dalam simpul yang terhubung dengan pointer seperti rantai. bukan bagaimana data disusun. Untuk objek list bertipe List.get(indeks) -. karena untuk setiap penyisipan atau pengurangan item.1. Tipe data abstrak didefinisikan dalam bentuk operasi yang bisa dilakukannya. Parameter indeks harus ada dalam rentang ini. Kita harus bisa memilih bentuk mana yang paling cocok dengan melihat operasi apa yang sering digunakan. termasuk size(). di mana indeks dimulai dari 0. yang tidak efisien dilakukan pada list berantai karena pada list berantai item dibandingkan satu per satu dari awal list hingga item ditemukan. Keduanya tersedia dalam bentuk generik dalam kelas java. Metode add(Object) digunakan untuk menambah objek di akhir list. 1.

untuk List ada tipe Iterator khusus yang bernama ListIterator yang memiliki kemampuan tambahan.indexOf(obj) -. List tidak diubah sama sekali. Metode ini tidak mengubah jumlah elemen di dalam list atau memindahkan elemen lain.mengembalikan Object pada posisi terakhir di dalam list.size().menyisipkan objek obj di dalam list pada posisi indeks. Jika objek yang dicari tidak ada maka nilai -1 akan dikembalikan. maka linkedlist. tetapi juga hasPrevious() dan previous sehingga kita bisa melakukan penelusuran mundur. • list. dan panah menunjukkan posisi dari iterator : • • . atau di akhir atau di depan list. ListIterator memiliki metode Iterator biasa. Jika linkedlist adalah objek bertipe LinkedList.getFirst() -.mencari objek obj di dalam list dan mengembalikan indeksnya pada list.removeLast() -.remove(indeks) -.listIterator() mengembalikan objek bertipe ListIterator dari list. Jika list adalah objek bertipe List maka metode list. dan item setelah posisi indeks akan digeser ke belakang. • linkedlist. mungkin ada baiknya jika iterator diibaratkan sebagai iterator yang menunjuk pada posisi di antara dua elemen. Jumlah item di dalam list akan bertambah satu. • linkedlist.getLast() -. obj) -. Nilai indeks harus berada pada rentang 0 hingga list. Dalam diagram berikut.add(indeks. Metode list.removeFirst() -.addFirst(obj) -. Object yang dihapus akan dikembalikan sebagai nilai keluaran.menambah obj pada posisi terakhir di dalam list. • linkedlist.addLast(obj) -.list. Kelas LinkedList memiliki beberapa metode tambahan yang tidak ada pada ArrayList. Metode-metode ini didefinisikan pada kelas ArrayList dan LinkedList.add(obj)) Metode-metode di atas sepertinya dibuat sehingga LinkedList mudah digunakan sebagai tumpukan atau antrian (lihat bagian sebelumnya dan bagian ini). akan mengembalikan Iterator yang bisa digunakan untuk menelusuri list tersebut dari awal hingga akhir. item dalam list digambarkan sebagai kotak. seperti hasNext() dan next().menghapus objek pada posisi indeks. dan mengganti isi objek yang sudah ada di posisi tersebut. Item setelah posisi ini akan digeser maju untuk mengisi kekosongan objek pada posisi tersebut setelah item dihapus. • linkedlist. Untuk mengerti lebih dalam.menambah obj pada posisi pertama di dalam list.iterator() yang didefinisikan pada interface Collection.menyimpan obj di dalam list pada posisi indeks.menghapus Objek pada posisi pertama di dalam list.mengembalikan Object pada posisi pertama di dalam list. Jika obj ada lebih dari satu dalam list. • list. jika ada.menghapus Objek pada posisi terakhir di dalam list. (Sama persis dengan linkedlist. List tidak diubah sama sekali.set(indeks. Akan tetapi. hanya indeks pertama yang dikembalikan. meskipun metode-metode ini hanya efisien pada ArrayList. • linkedlist. Misalnya kita bisa menggunakan LinkedList sebagai antrian dengan menambah item di akhir list (menggunakan metode addLast()) dan menghapus item dari awal list (menggunakan metode removeFirst()). • list. obj) -. Object yang dihapus akan dikembalikan sebagai nilai keluaran.

previous() memindahkan iterator ke kiri dan mengambalikan item yang dilewatinya. list yang digunakan oleh kelas LinkedList adalah list berantai ganda (doubly linked list).Jika iter adalah suatu ListIterator. maka iter. (Untuk pengetahuan. metode addLast() dan getLast() menjadi efisien karena kelas LinkedList juga memiliki variabel instansi yang menunjuk pada simpul terakhir di dalam list. Artinya. • iter. metode add() dari iterator itu bisa digunakan untuk menyisipkan item pada posisi yang tepat. . Sehingga metode next() dan previous() bisa diimplementasikan dengan efisien. setiap simpul pada list memiliki dua pointer.previous(). Item yang dihapus adalah item yang baru saja dilewati oleh iter. Pada posisi tersebut. static void sisipTerurut(List list. misalnya kita ingin menjaga agar suatu list selalu terurut dalam urutan menaik. • Metode iter.next() memindahkan iterator satu tempat ke kanan dan mengembalikan item yang baru dilewatinya.remove() menghapus item dari dalam list. kemudian memindahkan iterator melalui semua item yang lebih kecil dari item yang ingin sisipkan. kita bisa menggunakan ListIterator untuk menemukan posisi yang tepat di dalam list untuk meletakkan item baru itu. maka kita asumsikan bahwa item dalam list sudah mengimplementasikan interface Comparable dan memiliki metode compareTo(). yaitu satu yang menunjuk pada simpul setelahnya dan satu lagi menunjuk pada simpul sebelumnya. Idenya adalah memulai dari awal list. (Interface ini didiskusikan pada bagian sebelumnya). itemBaru. Artinya bisa berada di tengah-tengah dua item. di awal list atau di akhir list.next() atau iter.compareTo(item) harus didefinisikan untuk setiap item di dalam list. Ketika kita menambah item di dalam list.) Sebagai contoh untuk menggunakan ListIterator.add(Object) akan menambah Object ke dalam list pada posisi iterator sekarang. Comparable itemBaru) { • // Kondisi awal : Item dalam ist diurut dalam urutan menaik // // // menurut metode compareTo. • Metode iter. Untuk menentukan bahwa item baru tersebut lebih besar dari item di dalam list. Berikut ini adalah metode untuk melakukannya. Dan juga.

yaitu ketika iterator sampai pada akhir list. iter.hasNext() bernilai // false.listIterator().add(itemBaru). maka // perulangan while akan berhenti ketika iter.hasNext()) { Object item = iter.compareTo(item) <= 0) { // itemBaru harus ada SEBELUM item pada iter // Pindahkan iterator satu tempat sehingga // menunjuk pada posisi penyisipan yang benar. .next().previous(). // Pindahkan iterator sehingga menunjuk pada posisi yang tepat // Jika itemBaru lebih besar dari semua item di dalam list. } } iter. // dan pada akhir perulangan.// // Kondisi akhir : itemBaru yang sudah ditambahkan // // ada pada posisi yang benar. while (iter. if (itemBaru. break. sehingga list masih dalam keadaan terurut menaik ListIterator iter = list.

Akan tetapi metode ini akan berjalan sangat lambat untuk LinkedList karena get(indeks) pada LinkedList berjalan tidak efisien..sort(A). kelas Arrays memiliki 8 metode : satu metode untuk array Object dan masing-masing satu metode untuk tipe primitif byte. short.} // akhir sisipTerurut() Karena parameter pada metode ini bertipe List.komparator). • Collections. Item di dalam list harus mengimplementasikan interface Comparable.sort(list) digunakan untuk mengurut list dalam urutan menaik.sort(list. sehingga elemen terakhir menjadi elemen pertama dan sebaliknya. Kelas ini memiliki berbagai metode statik yang digunakan untuk membantu kelas-kelas koleksi : • Collections. Set (Himpunan) . • Arrays. Java tidak mendukung pemrograman generik untuk tipe primitif.Arrays.shuffle(list) digunakan untuk mengacak list. digunakan untuk mengurut list menggunakan komparator (pembanding) sendiri yang diberikan di dalam metode. Kenyataannya tidak ada.sort(A.sort(A) digunakan untuk mengurut array A.reverse(list) digunakan untuk membalik urutan elemen di dalam list. hingga A[indeksAkhir . Jawabannya adalah ya. .Collections.1] dalam urutan menaik. kita tidak perlu membuat metode pengurutan sendiri. long.. Untuk mengimplementasikan perintah Arrays. float. Tentunya kita akan bertanya apakah ada metode pengurutan untuk array biasa. dan char. N) bisa digunakan untuk mengurut N elemen pertama di array A. • Collections. A[indeksAwal + 1]. asalkan tipe dasar A adalah tipe dasar primitif (kecuali boolean) atau jika A adalah array Object yang mengimplementasikan interface Comparable. misalnya pada String. Akan tetapi metode untuk mengurut List tersedia sebagai metode statik dalam kelas java. Array. Kita akan lihat contohnya nanti. 0. • Collections. maka metode ini bisa digunakan pada ArrayList maupun LinkedList. int. Perintah ini mengurut array dari elemen A[indeksAwal].obj).util. dan dengan menggunakan metode get(indeks) dan add(indeks. dan kira-kira akan berjalan dengan tingkat efisiensi yang sama untuk kedua jenis list.sort(A. Komparator adalah objek yang memiliki metode compare() yang digunakan untuk membandingkan dua objek. Ini penting karena array kadang hanya terisi sebagian. indeksAkhir) digunakan untuk mengurut sebagian array saja. indeksAwal. Pengurutan List Mengurutkan list adalah operasi yang cukup umum dilakukan. Mungkin akan lebih mudah untuk menulis metode di atas dengan menggunakan indeks seperti pada array. • Arrays.util. Karena metode pengurutan yang cukup efisien sudah diberikan untuk List. dan seharusnya ada metode untuk mengurut list di dalam interface List. Pengurutan array juga tersedia dalam metode statik dalam kelas java. double.

Dengan menggunakan TreeSet. kita bisa memastikan bahwa kita bisa mencapai semua simpul daunnya dengan secepat mungkin.iterator().TreeSet dan java. program tersebut dapat dibuat dengan sangat mudah.HashSet. Pada implementasi TreeSet. yaitu java. Objek obj1 dan obj2 adalah objek yang sama jika obj1. Dengan menggunakan pohon seimbang. menjadi : TreeSet kata = new TreeSet(). TreeSet sangat berguna untuk beberapa aplikasi. Misalnya.compareTo(obj2) harus bisa membandingkan 2 objek obj1 dan obj2 dengan baik. Selain sebagai Set. List kata-kata dalam artikel itu harus diurutkan.equals(obj2) menghasilkan nilai true (lihat bagian sebelumnya untuk penjelasan tentang ini). kemudian kata-kata yang sama dihapus. Set mengimplementasikan metode umum pada Collection dengan sedikit modifikasi sehingga tidak memiliki objek yang sama di dalamnya. elemen di dalamnya disimpan dalam bentuk yang mirip dengan pohon pengurutan biner (lihat bagian sebelumnya). Atau dengan kata iain. kita akan membuat program untuk menghitung semua kata dalam suatu artikel dan menampilkan semua kata yang ditemukan.Himpunan (set) adalah kumpulan Object yang mana tidak boleh ada dua dari objek yang sama di dalam satu himpunan.add(kt). Karena TreeSet mengurutkan elemen-elemennya dan menjamin tidak ada duplikasi objek. objek yang disimpan dalam TreeSet harus mengimplementasikan interface Comparable dan obj1. Java memiliki dua kelas yang mengimplementasikan interface Set. Atau cara lainnya adalah dengan menggunakan Comparator yang bisa dimasukkan sebagai parameter dalam konstruktor ketika TreeSet dibuat. jika set adalah objek bertipe Set maka set.util. Di sini Comparator digunakan untuk membandingkan objek yang akan dimasukkan di dalam set. . Iterator dari suatu TreeSet akan mengunjungi elemen dalam set tersebut dalam urutan menaik.util. Misalnya. Iterator iter = kata. objek bertipe TreeSet memiliki sifat di mana elemen-elemennya terurut dalam urutan menaik.add(obj) tidak melakukan apa-apa jika obj sudah ada di dalam set. Pohon yang digunakan bersifat seimbang (balanced) yang artinya semua simpul daunnya berjarak sama dari akar pohonnya. karena objek yang disimpan harus bisa diurutkan. TreeSet tidak bisa menyimpan semua objek. while masih ada data dari input : kt = kata berikutnya dari input kata. Menambah dan mengurangi simpulnya juga bisa dilakukan dengan cepat.

pencarian.addAll(kol). Pada Java. set. Atau kita bisa menyingkat keempat baris kode di atas dalam satu baris kode : ArrayList list = new ArrayList( new TreeSet(kol) ). Karena berbentuk Set. Jika kita ingin data tersebut disimpan dalam struktur data lain. Sebetulnya. Semua item dalam Collection ditambahkan ke dalam koleksi baru ketika dibuat. Hasilnya adalah list terurut dengan elemen dari kol tanpa duplikasi.) HashSet mengimplementasikan tabel hash yang akan kita bahas di bagian berikutnya.addAll(set). bahkan lebih cepat lagi dari TreeSet. Pada bahasa Smalltalk. atau TreeSet yang membolehkan duplikasi. dan penghapusan dilakukan dengan sangat efisien pada tabel hash. Perintah baris kedua di atas menambah semua elemen dari kol ke dalam set. set. misalnya kol adalah koleksi String (atau tipe lain yang mengimplementasikan compareTo()). Misalnya.while (iter. ArrayList list = new ArrayList(). Jadi new TreeSet(kol) membuat TreeSet yang memiliki elemen yang sama seperti koleksi kol. kelas koleksi Java memiliki konstruktor yang bisa mengambil parameter berbentuk Collection. (Sepertinya tidak ada struktur data list dengan duplikasi pada Java. . list. struktur data seperti ini disebut bag (kantong).next() ke layar. tidak ada struktur data seperti ini. kita bisa mengubahnya dengan mudah. Kita bisa menggunakan TreeSet untuk mengurutkan item dari kol dan menghapus duplikasi dengan : TreeSet set = new TreeSet(). Elemen pada HashSet tidak disimpan dalam urutan tertentu. untuk saat ini. untuk membuat ArrayList dari TreeSet. Pada bahasa pemrograman C++ struktur data ini disebut multiset. bisa kita tulis dengan : TreeSet set = new TreeSet(). Ini adalah contoh dari keampuhan pemrograman generik.hasNext()): Tampikan iter. Karena berbentuk TreeSet maka semua elemennya akan terurut. Operasi penambahan.addAll(kol). Iterator dari HashSet akan mengunjungi elemen-elemen pada HashSet dalam urutan yang sepertinya acak dan mungkin berubah jika elemen baru ditambahkan. maka duplikasi akan dihapus. Contoh lainnya.

• map. maka berikut ini adalah beberapa metodenya : • map.. N-1. Jika map tidak memiliki nilai yang ditunjuk oleh kunci.size() -. .mengembalikan int yang berisi jumlah pasangan asosiasi pada map. Keduadua kunci dan nilai bisa berupa objek apa saja. objek yang digunakan sebagai "indeks" disebut kunci (key).. 1..Map. . akan tetapi pada sembarang Object. Suatu peta (map) adalah generalisasi dari array.put(kunci. Kita bisa menggunakan HashSet jika elemen yang kita akan masukkan tidak bisa dibandingkan.get(kunci)" sama dengan perintah "A[kunci]" pada array A.containsValue(nilai) -. Perintah ini mirip dengan "A[kunci] = nilai" pada array. map didefinisikan dalam interface java.. Dalam Java.get(kunci) -.jika map2 adalah map lain. Java tidak menggunakan perintah yang sama pada map. (Akan tetapi pada map tidak ada pengecualian IndexOutOfBoundsException) • map. Tapi ingat juga bahwa mungkin saja kuncinya ada akan tetapi memang menunjuk pada nilai null. Beberapa bahasa pemrograman menggunakan istilah array asosiatif (associative array) karena kesamaan perintah dengan array biasa. Jika map adalah variabel dengan tipe Map.containsKey(kunci) -. atau dengan kata lain menghapus pasangan kunci dan nilai pada map sekaligus. operasi ini tidak dilakukan pada bilangan 0. . Seperti array. Kelas Map Suatu array yang berisi N elemen bisa juga dilihat sebagai asosiasi (pemetaan) antara elemennya dengan bilangan 0. • map.Karena elemen pada HashSet tidak diurutkan.mengembalikan Object yang ditunjuk oleh kunci.Jika map memiliki kunci yang menunjuk pada suatu nilai. akan tetapi satu nilai bisa ditunjuk oleh beberapa kunci. atau urutannya tidak penting. 1.. Akan tetapi pada map. maka perintah ini akan mengkopi semua isi pada map2 ke dalam map.util.mengembalikan nilai boolean true jika map memiliki nilai yang ditunjuk oleh kunci apapun.putAll(map2) -. Jika i adalah salah satu bilangan ini. Pada map. nilai) -. Jika map tersebut telah memiliki kunci maka nilai yang ditunjuk akan diganti dengan yang baru diberikan. yang memiliki beberapa metode untuk bekerja dengan map. map juga memiliki operasi untuk mengambil dan meletakkan elemen. • map.Mengisi map dengan pasangan kunci dan nilai.mengembalikan nilai boolean true jika map memiliki kunci yang merujuk pada suatu nilai • map. kita bisa menuliskan A["joko"] yang digunakan untuk memetakan "joko" pada suatu elemen di dalam array. akan tetapi idenya serupa : Map adalah seperti array yang indeksnya adalah objek sembarang. maka nilai null akan dikembalikan. Satu kunci hanya boleh menunjuk pada satu nilai. Pada bahasa pemrograman tersebut. Menggunakan "map. Objek yang ditunjuk oleh indeks tersebut disebut nilai (value). bukan integer. maka kita bisa mengambil elemen yang dipetakan oleh bilangan i. N-1 yang merupakan indeksnya. perintah ini akan menghapus kunci beserta nilai yang ditunjuknya. maka semua objek (termasuk yang tidak mengimplementasikan interface Comparable) bisa dimasukkan dalam HashSet. • map. atau jika kecepatan lebih dipentingkan. dan juga kita bisa meletakkan elemen baru pada posisi ke-i.remove(kunci) -.

Hampir semua operasi dapat berjalan lebih cepat pada HashMap dibandingkan dengan TreeMap. } public String ambilNomor(String nama) { // Mengambil nomor telepon dari nama // Kembalikan null jika tidak ada nomor telepon untuk nama tsb return (String)info.get(nama). maka hanya objek yang bisa dibandingkan saja yang bisa digunakan sebagai kunci.put(nama. kita tidak perlu lagi membuat kelas baru untuk mengimplementasikan BukuTelepon tersebut. pasangan kunci/nilai disimpan secara berurutan dalam pohon terurut. nomor) dan ambilNomor(nama). Atau dengan kata lain.isEmpty() -. HashMap tidak menyimpan pasangan kunci/nilai dalam urutan tertentu. String nomor) { // Menyimpan nomor telepon pada nama yang sesuai info. atau Comparator harus diberikan pada konstruktornya pada saat TreeMap dibuat. Secara umum. Artinya kelas kunci harus berupa kelas yang mengimplementasikan interface Comparable. Metode put dan get jelas merupakan metode yang paling sering digunakan dalam map. Artinya. Supaya bisa bekerja dengan benar. Dalam banyak aplikasi.HashMap.menghapus semua pasangan asosiasi dalam map.mengembalikan boolean true jika map tidak berisi pasangan asosiasi apa-apa.nomor). public class BukuTelepon { // Menyimpan data telepon private HashMap info = new HashMap().• • map. yaitu pada kelas BukuTelepon yang memiliki pasangan nama/nomor telepon.clear() import java. Misalnya progrma direktori telefon. Kelas ini memiliki operasi tambahEntri(nama. menggunakan map sama mudahnya dengan menggunakan array biasa. Akan tetapi menggunakan Map mungkin memiliki sedikit kerugian. Dalam TreeMap. artinya kita bisa langsung menggunakan Map. di mana nama dan nomor bertipe String. yaitu diurut berdasarkan kuncinya. karena kita dipaksa harus menggunakan Object bukan String. metode ini mungkin hanya metode ini yang kita butuhkan. public void tambahEntri(String nama. Java memiliki dua kelas yang mengimplementasikan interface Map. Dalam aplikasi pemrograman sebenarnya. sehingga tidak ada batasan objek apa yang bisa disimpan di dalamnya. gunakan HashMap. lebih baik menggunakan HashMap kecuali kita butuh struktur data dalam urutan tertentu yang hanya bisa dilakukan dengan TreeMap. jika kita hanya menggunakan perintah put dan get. yaitu : TreeMap dan HashMap. } } // akhir kelas BukuTelepon . maka kita bisa membuat kelas baru yang menggunakan Map dalam implementasinya.util. -. Jika ini masalahnya. seperti berikut : map.

Akan tetapi. maka set kuncinya adalah set yang terurut.println("Map ini memiliki asosiasi sebagai berikut:"). Hasil yang dikembalikan oleh map.hasNext()) { Object knc = kunciIter. Tampilan tidak bisa digunakan untuk menambah data.out. dan iteratornya akan mengunjungi kunci-kuncinya dalam urutan menaik." + nilai + ")" ). Jika map adalah variabel bertipe Map. Kita bisa menggunakan iterator untuk melakukan penelusuran isi Set. while (kunciIter. Kita bisa juga menggunakan iterator untuk kunci dari map.keySet() tidak membuat set baru. artinya jika kita menghapus elemen dari dalam tampilan ini. } Jika map adalah suatu TreeMap. // Set kunci dari map Iterator kunciIter = kunci.next(). // Ambil nilai yang ditunjuk oleh kunci System. Karena kembalian dari metode get() bertipe Object maka type cast menjadi penting sebelum nilainya bisa digunakan.keySet() disebut tampilan (view) dari objek-objek yang disimpan di dalam map. maka perintah ini akan cukup efisien untuk digunakan pada map yang sangat besar sekalipun. "Tampilan" yang dikembalikan metode ini berhubungan langsung dengan map aslinya. maka hasilnya akan dikembalikan dalam bentuk Set.get(nama) di-type-cast ke dalam String. artinya map tidak mengimplementasikan semua operasi yang didefinisikan pada interface Collection.iterator().get(knc). nilai kembalian dari info.println( " (" + knc + ". dan submap Map sebenarnya bukan merupakan Collection.keySet() akan mengembalikan semua objek kunci pada map. karena fungsinya hanya sebagai tampilan. Karena di dalam map tidak ada kunci yang sama. Tampilan. maka metode map. karena map tidak memiliki iterator. . System.Dalam metode ambilNomor di atas.out. Karena map. kemudian menelusurinya. Dengan "membungkus" Map di dalam kelas BukuTelepon. Java memiliki cara lain untuk melakukan penelusuran item pada map.keySet(). // Ambil kunci berikut Object nilai = map. subset. maka kunci beserta nilai yang ditunjuk di dalam map akan juga dihapus. kita menyembunyikan type-cast dalam implementasinya sehingga interaksi kelas ini dengan kelas lain yang menggunakannya menjadi lebih natural. misalnya : Set kunci = map.

Entry pasangan = (Map.out. Ada juga metode setValue(nilai) untuk mengisi nilainya.entrySet().iterator(). Metode map.Entry)entriIter. Jika map adalah variabel bertipe Map. Sehingga kita bisa membuat fungsi yang sama dengan di atas dengan lebih efisien. while (entriIter." + nilai + ")" ). Iterator entriIter = entri.next(). interface List memiliki sublist yang untuk melihat sebagian isi list. int indeksAkhir) mengembalikan sebagian list yang terdiri dari elemen pada posisi antara indeksAwal hingga indeksAkhir (termasuk indeksAwal tapi tidak termasuk indeksAkhir. Setiap elemen dalam set ini adalah objek bertipe Map. Akan tetapi tetap bisa digunakan sebagaimana kelas-kelas lainnya). maka metode : map. } Map bukan satu-satunya tempat di mana tampilan bisa diambil. Kita bisa menggunakan set ini untuk mencetak semua pasangan kunci dan nilainya. yaitu Set entri = map. Informasi dalam kelas ini sama dengan informasi dalam map itu sendiri.println( " (" + kunci + ".Interface Map memiliki 2 jenis tampilan lain. yang lebih efisien daripada menggunakan kunci kemudian mengambil kembali isinya dari dalam map seperti contoh di atas.values() mengembalikan Collection yang berisi semua nilai yang disimpan dalam map.getKey().Entry (Kelas ini adalah kelas statik bertingkat. akan tetapi Set yang dikembalikan menampilkan jenis informasi yang berbeda.) Tampilan ini memungkinkan .entrySet() mengembalikan Set yang berisi asosiasi (kunci dan nilainya) di dalam map. System. sehingga namanya memiliki tanda titik. Object kunci = pasangan .println("Map ini berisi asosiasi sebagai berikut:"). Misalnya.Entry berisi hanya satu pasangan kunci dan nilai.getValue().out. dan memiliki metode getKey() dan getValue() untuk mengambil kunci dan nilainya. Objek Map. Metode List subList(int indeksAwal.hasNext()) { Map. // Ambil kunci dari pasangan Object nilai = pasangan . Nilai kembaliannya bukan Set karena suatu map bisa berisi nilai yang sama. // Ambil nilainya System.

Kelas TreeMap memiliki tiga tampilan submap.subSet(dariElemen.kita untuk melakukan operasi apapun seperti pada list biasa. Ada juga tampilan map."). Perubahan yang dilakukan pada sublist akan juga mempengaruhi list aslinya.subMap(dariKunci. "n") akan berisi semua elemen pada kata yang dimulai dari huruf m. jika kata adalah suatu TreeSet di mana semua elemennya adalah String berisi huruf kecil. // Submap ini berisi semua elemen di mana kuncinya lebih // besar dari "M" dan kurang dari (tapi tidak termasuk) "N" if (ems. Kita bisa mencetak semua entri pada bukuHitam yang namanya dimulai dengan "M" seperti berikut : Map ems = bukuHitam.headMap(hinggaKunci) dan map. Jika set adalah suatu TreeSet. Artinya membuat subset tidak mengkopi elemen. dan set. Begitu juga dengan set. kita bisa membuat tampilan yang merupakan subset dari suatu set.isEmpty()) System. maka kata. Misalnya.subSet("m". maka set. Jika map suatu variabel bertipe TreeMap. akan tetapi sublist bukan list terpisah. bukuHitam adalah suatu TreeMap di mana kuncinya adalah nama dan nilainya adalah nomor telepon.out.entrySet().subMap("M". Misalnya.headSet(hinggaElemen) berisi semua elemen dari set yang kurang dari [code]hinggaElemen. Subset ini adalah tampilan yang merupakan bagian dari set aslinya. hinggaKunci) mengembalikan tampilan yang berisi semua pasangan kunci/nilai dari map yang kuncinya ada di antara dariKunci dan hinggaKunci (termasuk dariKunci tapi tidak termasuk hinggaKunci). // Iterator ini akan menelusuri entri pada submap ems . Submap mirip dengan subset.tailSet(dariElemen) adalah tampilan yang berisi semua elemen yang lebih besar atau sama dengan dariElemen. hinggaElemen) mengembalikan [code]Set yang berisi elemen-elemen set antara dariElemen hingga hinggaElemen (termasuk dariElemen tapi tidak termasuk hinggaElemen).iterator().println("Tidak ada elemen yang dimulai dengan M.tailMap(dariKunci) seperti aturan pada subset. else { Iterator iter = ems. Tampilan set. Submat adalah Map yang berisi subset dari kunci dan nilai pada Map aslinya. maka map. dan perubahan pada subset (misalnya penambahan dan pengurangan elemen) juga mempengaruhi set aslinya."N").

maka semua nilainya berisi null. Pasangan kunci/nilai dengan kunci N bisa disimpan dalam A[N]. maka kita harus mengecek isinya satu per satu hingga item yang kita cari ditemukan. akan tetapi programmer harus kenal dengan tabel hash dan cara kerjanya. Jika tabel hash digunakan untuk mengimplementasikan set. jika kuncinya bertipe int.getKey() + ": " + entri. Tabel hash merupakan solusi elegan untuk menyelesaikan masalah pencarian. Bagaimana caranya? Jika kuncinya adalah integer antara 0 hingga 99. Dalam pohon pencarian biner.next(). Kunci ini akan membawa kita langsung ke pasangan kunci/nilai.println( entri. Untuk mencari suatu item di dalam list tidak terurut. Dalam semua algoritma pencarian. Kita masih harus mencari kuncinya di dalam tabel. untuk mencari suatu item. System.while (iter. tapi kira-kira seperti ini). Kita hanya perlu membuat submap yang berisi semua kunci antara 00:00 1 Maret 2009 hingga 00:00 2 Maret 2009 kemudian mencetak isi submap tersebut. sehingga kita bisa mencari elemen pada rentang nilai tertentu. Tabel Hash HashSet dan HashMap diimplementasikan dengan struktur data yang disebut tabel hash. Jika kita mencari pasangan kunci/nilai dalam tabel hash. Jika kita mengetahui kuncinya. bukan hanya pencarian satu nilai saja. Kita tidak perlu mengerti tabel hash untuk menggunakan HashSet atau HashMap. dan kita bisa pergi ke lokasi di mana nilai tersebut disimpan secara langsung. menyimpan pasangan kunci/nilai. Kita tidak perlu mencari item lainnya (Sebenarnya tidak sepenuhnya benar. ada banyak kemungkinan untuk suatu jenis kunci. maka kita bisa mencari nilainya di dalam tabel. kita bisa langsung ke tempat di mana item tersebut berada. Masalahnya. Tipe pencarian seperti ini disebut pencarian rentang (subrange query). seperti HashMap. Misalnya. kita bisa menyimpan pasangan kunci/nilai dalam array A yang berisi 100 elemen. Map.out.hasNext()) { // Get the next entry and print its key and value. Lokasi di mana pasangan kunci/nilai ini berada dihitung dari kuncinya: Kita hanya melihat kuncinya. kita harus mencari item yang tidak kita inginkan. Tabel hash.getValue() ). kita harus mulai dari akar dan turun ke bawah hingga item yang dicari ditemukan. dan misalnya kita ingin mencari semua item yang terjadwal 1 Maret 2009. Misalnya pada database disimpan jadwal yang disimpan dalam bentuk TreeMap di mana kuncinya adalah waktu.tentunya .Entry entri = iter. } } Subset dan submap mungkin menjadi cara terbaik untuk melakukan pencarian. maka kita perlu 4 milyar lokasi untuk menyimpan semua kuncinya dalam array -.

kemudian langsung pergi ke lokasi array di ditunjuk oleh kode hash tersebut. hampir semua list berantai berisi nol atau satu elemen saja. maka sangat mungkin kita memiliki situasi di mana satu lokasi array digunakan dua atau lebih kunci. Tabrakan bukan kesalahan. Jika kode hashnya 17. dan seterusnya. maka jumlah kemungkinan kuncinya tidak terbatas. Meskipun kode hash dari suatu kunci mungkin tidak membawa kita . tidak ada item dengan kode hash 1. lihat langsung pada array nomor 17. Indeks tidak sama dengan kunci. akan tetapi indeks dihitung dari kunci. dengan rata-rata panjang list kurang dari 1. yang disebut fungsi hash. Kita tidak bisa menolak suatu kunci karena memiliki kode hash yang sama dengan kunci lain. maka kedua item tersebut akan ada pada list yang sama. Pada gambar di atas. Untuk mencari kunci di dalam tabel hash. Jika kuncinya berupa string dengan panjang yang tidak tentu. Sekarang. hanya ada satu item dengan kode hash 0. Tabel hash harus bisa menangani tabrakan dengan cara yang baik.pemborosan memori yang sia-sia jika kita hanya ingin menyimpan katakan ribuan item saja. Fungsi tertentu akan menghitung kode hash. Strukturnya bisa digambarkan sebagai berikut. Jika dua item memiliki kode hash yang sama. Dalam tabel hash yang digunakan pada Java. Hal ini disebut tabrakan (collision). dua item dengan kode hash 2. Indeks array dari hasil perhitungan kunci disebut kode hash untuk kunci tersebut. setiap lokasi array sebetulnya adalah suatu list berantai yang berisi pasangan kunci/nilai (atau mungkin juga list kosong). tabel hash menyimpan datanya dalam array. Walau bagaimanapun. karena hanya ada lebih sedikit lokasi array dibandingkan kemungkinan kuncinya. Pada tabel hash yang dirancang dengan benar. kita hanya pelu menghitung kode hash kunci tersebut. sehingga kita tidak mungkin menggunakan array untuk menyimpan semua kemungkinan kuncinya.

Kode hash ini bisa dihitung dengan menggunakan Math. katika jumlah item melebihi 75% ukuran array. kita akan melihat input output pada file dan koneksi jaringan (network). dan Writer . Ketika objek obj disimpan dalam tabel yang berukuran N. Misalnya dalam kelas String.. kita bisa berharap bahwa metode equals() dan hashCode sudah dibuat dengan benar. Banyak subrutin yang digunakan untuk bekerja dengan I/O melemparkan pengecualian yang wajib ditangani. Untuk kelas standar Java.in) adalah contoh aliran.out) dan standar input (System. Jika suatu kelas memiliki metode equals() sendiri. input/output pada file dan jaringan dilakukan berdasarkan aliran (stream). Artinya subrutin tersebut harus dipanggil di dalam pernyataan try . kita membutuhkan pengetahuan tentang pengecualian. bukan lokasi memorinya. Supaya hash bisa bekerja dengan benar. Pada bab ini. Pada Java. akan tetapi untuk kelas yang kita buat sendiri kita mungkin harus membuat fungsi hash sendiri. catch sehingga pengecualian yang terjadi bisa ditangani dengan baik. Metode hashCOde() pada kelas String itu juga didefinisi ulang sehingga kode hash dari string dihitung berdasarkan karakter di dalam String. metode equals() didefinisi ulang sehingga dua objek String dianggap sama jika urutan karakter dalam String tersebut sama. dan jika objek tersebut akan digunakan sebagai kunci pada tabel hash.Pengenalan Input/Output (I/O) Program komputer bisa berguna jika ia bisa berinteraksi dengan dunia lain. akan tetapi tidak akan lebih dari satu atau dua item yang harus kita cari sebelum kita sampai pada item yang kita inginkan. Interaksi di sini maksudnya input/output atau I/O. Standar output (System.hashCode()) % N. dua objek yang sama menurut metode equals() seharusnya memiliki kode hash yang sama. (Nilai mutlak diperlukan karena obj. Dalam kelas Object metode equals() dan hashCode() dihitung berdasarkan lokasi memori di mana objek tersebut disimpan.. dan kita tidak ingin nilai negatif sebagai indeks array kita). Untuk bekerja dengan file dan jaringan.langsung pada kunci yang kita mau. jumlah item dalam tabel hash harus kurang dari besarnya array. di mana semua objek dapat melakukan perintah I/O yang sama. maka array tersebut akan diganti dengan array yang lebih besar dan semua item pada array yang lama dipindahkan ke array baru.hashCode() dengan N. banyak kelas yang memiliki metode equals() sendiri. Reader. Kelas Object memiliki metode bernama hashCode() yang mengembalikan nilai bertipe int.hashCode() bisa bernilai negatif. Akan tetapi seperti disebutkan sebelumnya. yaitu sisa pembagian dari nilai mutlak obj. maka kode hash antara 0 hingga N-1 diperlukan. Agar bekerja dengan benar. • Stream.abs(obj. Bab X . maka kelas tersebut juga harus mendefinisikan metode hashCode(). Pada Java. yang telah dibahas sebelumnya.

masih akan ada beberapa terjemahan yang dilakukan. Salah satu kemajuan terbesar dalam sejarah pemrograman adalah adanya konsep (atau abstraksi) untuk memodelkan perangkat I/O. Jika kita menulis angka ke suatu OutputStream. maka kompleksitasnya akan tak lagi bisa ditangani. Untuk lebih lengkapnya. Untuk membaca dan menulis data karakter yang bisa dimengerti manusia. Semua kelas aliran karakter merupakan kelas turunan dari salah satu dari kelas abstrak ini. Komputer bisa terhubung dengan beragam jenis input dan output dari berbagai perangkat. seperti dari editor teks. Akan tetapi data tersebut bisa dibaca kembali oleh InputStream. dan Writer Tanpa bisa berinteraksi dengan dunia lain. Proses baca tulis data akan menjadi sangat efisien. dari deretan karakter menjadi rangkaian bit yang dimengerti komputer. Karakter disimpan dalam komputer dalam nilai Unicode 16-bit. komputer harus bisa menerjemahkannya ke dalam rangkaian karakter yang bisa dibaca maunsia. kita membacanya sebagai rangkaian huruf yang kita terjemahkan sebagai angka. Java memiliki dua kategori besar untuk aliran : aliran byte untuk data mesin (byte stream). dan aliran karakter (character stream) untuk data yang bisa dibaca manusia. Jika bahasa pemrograman harus dibuat secara khusus untuk setiap jenis perangkat. Data yang bisa dibaca manusia adalah data dalam bentuk rangkaian huruf. Objek yang membaca data dari aliran byte diturunkan dari kelas abstrak InputStream. kita harus ingat bahwa ada dua kategori data secara umum : data yang dibuat oleh mesin. Interaksi suatu program dengan dunia lain sering disebut input/output atau I/O. Data yang dibuat mesin ditulis dengan model yang sama dengan bagaimana data tersebut disimpan di dalam komputer. abstraksi ini disebut dengan aliran (stream). kita tidak akan bisa membaca data tersebut karena ditulis dalam bahasa mesin. Jika suatu angka akan ditulis dalam aliran Writer. (Meskipun untuk data yang terdiri dari karakter. kelas utamanya adalah Reader dan Writer. Membaca angka dari aliran Reader menjadi variabel numerik juga harus diterjemahkan. Setiap objek yang mengeluarkan data ke aliran byte masuk sebagai kelas turunan dari kelas abstrak OutputStream. yaitu rangkaian nol dan satu. Dalam Java. karena tidak ada penerjemahan yang harus dilakukan : bit yang digunakan untuk menyimpan data di dalam memori komputer hanya dikopi dari dan ke aliran tersebut. Bagian ini akan memperkenalkan tentang aliran. Bagi orang yang . Reader.13159. Sejak dulu.• • • File Jaringan (network) Pemrograman Serentak (Concurrency) Stream. suatu program tidak ada gunanya. Angka ini akan ditulis dalam komputer sebagai rangkaian bit yang kita tidak mengerti. akan tetapi tidak menjelaskan dengan komplit. salah satu tantangan terbesar untuk mendesain bahasa pemrograman baru adalah mempersiapkan fasilitas untuk melakukan input dan output. Ketika kita membaca suatu bilangan 3. Ada banyak kelas yang diturunkan dari kedua kategori ini. Ketika berhubungan dengan input/output. Untuk menghadapi kedua jenis data ini. silakan lihat dokumen resmi Java. dan data yang bisa dibaca manusia.

misalnya tombol enter. Yang akan kita gunakan adalah kelas turunan dari InputStream yang memiliki beberapa metode input yang lebih beragam daripada InputStream itu sendiri. dan juga menangani alfabet lain yang digunakan negara lain. Kelas aliran standar yang akan dibahas berikutnya didefinisikan dalam paket java. Akan tetapi InputStream tidak memiliki metode untuk membaca jenis data lain.*" di awal kode sumber kita.io beserta beberapa kelas bantu lainnya. dsb. yaitu metode public void write(int b) throws IOException . kelas InputStream memiliki metode instansi public int read() throws IOException untuk membaca satu byte data dari aliran input. Begitu juga dengan kelas OutputStream memiliki metode output primitif untuk menulis satu byte data ke aliran output. Jika tidak. Jika kita ingin data yang kita baca/tulis untuk bisa dibaca manusia. Misalnya. System. Kita harus mengimpor kelas-kelas tersebut dari paket ini jika kita ingin menggunakannya dalam program kita. Dan juga ada kelas aliran yang digunakan untuk membaca dan menulis data dari dan ke memori komputer. karena GUI memiliki aliran I/O tersendiri.menggunakan alfabet biasa. artinya kita harus menggunakan metode read() di dalam penyataan try atau mengeset subrutin untuk throws IOException. escape. • • Operasi pada Aliran (Stream) Berbagai Jenis InputStream dan OutputStream Operasi pada Aliran (Stream) Kelas dasar I/O Reader.out sebenarnya adalah aliran byte dan bukan aliran karakter. yang hanya menggunakan 8-bit. maka pengecualian IOException akan dilemparkan. tanda panah. Jika ada kesalahan yang terjadi pada saat pengambilan input. Writer. Karena IOException adalah kelas pengecualian yang harus ditangani.in dan System. Jika sampai pada akhir dari aliran input . InputStream dan OutputStream hanya menyediakan operasi I/O sangat dasar. gunakan aliran byte. metode read() akan mengembalikan nilai -1. Artinya dengan menggunakan "import java. data karakter biasanya disimpan dalam file dalam kode ASCII. seperti int atau double dari aliran. Ini bukan masalah karena dalam prakteknya kita tidak akan menggunakan objek bertipe InputStream secara langsung.io. Kelas Reader dan Writer akan menangani perubahan dari 16bit ke 8-bit dan sebaliknya. karenanya bisa menangani input selain alfabet. Aliran tidak digunakan dalam GUI.) Adalah hal yang mudah untuk menentukan apakah kita harus menggunakan aliran byte atau aliran karakter. Akan tetapi kelaskelas ini digunakan juga untuk file atau komunikasi dalam jaringan. (Lihat kembali pembahasan tentang pengecualian di bab sebelumnya) Kelas InputStream juga memiliki metode untuk membaca beberapa byte data dalam satu langkah ke dalam array byte. Atau bisa juga digunakan untuk komunikasi antar thread yang sedang bekerja secara bersamaan. maka kita gunakan aliran karakter.

Dalam prakteknya kita akan menggunakan kelas turunan dari kelas-kelas dasar ini. Jika kita memiliki objek bertipe Writer atau turunannya. dan kita ingin menggunakan metode pada PrintWriter untuk menulis data. maka kita bisa membungkus objek Writer dalam objek PrintWriter. sehingga kita juga bisa melakukan baca tulis dari objek yang sama dengan tambahan kemampuan dalam objek pembungkusnya. Kelas Reader dan Writer memiliki operasi dasar yang hampir sama. Untuk lengkapnya. Salah satu hal menarik dari paket I/O pada Java adalah kemungkinan untuk menambah kompleksitas suatu aliran dengan membungkus aliran tersebut dalam objek aliran lain. Artinya kita hanya perlu membuat antar muka yang lebih baik untuk aliran output yang sama. Ketika kita menulis data ke printableBaskomKarakter dengan menggunakan metode pada PrintWriter yang lebih canggih. Misalnya. Artinya operasi baca tulis akan mengambil dan menulis nilai char bukan byte. maka kita bisa membuat PrintWriter printableBaskomKarakter = new PrintWriter(baskomKarakter). Atau dengan kata lain misalnya kita bisa menggunakan PrintWriter untuk menulis file atau mengirim data pada jaringan. kita hampir pasti akan menggunakan kelas turunannya yang mampu menangani operasi yang lebih kompleks. PrintWriter adalah kelas turunan dari Writer yang memiliki metode tambahan untuk menulis tipe data Java dalam karakter yang bisa dibaca manusial. Contoh jika baskomKarakter bertipe Writer. Objek pembungkus ini juga berupa aliran.Tapi. akan tetapi kelas ini berorientasi karakter (karena digunakan untuk membaca dan menulis data yang bisa dibaca manusia). metode pada kelas PrintWriter memiliki metode sebagai berikut : // Metode untuk menulis data dalam // bentuk yang bisa dibaca manusia public void print(String s) public void print(char c) public void print(int i) public void print(long l) public void print(float f) public void print(double d) public void print(boolean b) . maka data tersebut akan ditempatkan di tempat yang sama dengan apabila kita menulis langsung pada baskomKarakter. yaitu read dan write.

Akan tetapi. .// Menulis baris baru ke aliran public void println() // Metode ini sama dengan di atas // akan tetapi keluarannya selalu // ditambah dengan baris baru public void println(String s) public void println(char c) public void println(int i) public void println(long l) public void println(float f) public void println(double d public void println(boolean b) Catatan bahwa metode-metode di atas tidak pernah melempar pengecualian IOException. Kelas PrintWriter menangkap pengecualian IOException secara internal. Akan tetapi. Ketika kita menggunakan metode PrintWriter untuk menulis data ke aliran. Bagaimana caranya jika kita ingin membuat data dalam bentuk bahasa mesin? Paket java. DataOutputStream berhubungan erat dengan OutputStream seperti hubungan antara PrintWriter dan Writer.io memiliki kelas aliran byte. dan mengeset nilai tertentu di dalam kelas ini jika kesalahan telah terjadi. yaitu DataOutputStream yang bisa digunakan untuk menulis suatu data ke dalam aliran dalam format biner. jika kita ingin membuat progam yang tangguh tentunya kita harus selalu memanggil checkError() untuk melihat apakah kesalahan telah terjadi ketika kita menggunakan salah satu metode pada PrintWriter. data tersebut diubah menjadi rangkaian karakter yang bisa dibaca oleh manusia. kelas PrintWriter memiliki metode public boolean checkError() yang akan mengembalikan true jika ada kesalahan yang terjadi ketika menulis ke dalam aliran. Sehingga kita bisa menggunakan metode pada PrintWriter tanpa khawatir harus menangkap pengecualian yang mungkin terjadi.

Misalnya. Akan tetapi Java memiliki cara untuk melakukan input dan output isi objek secara otomatis. Akan tetapi kita tetap bisa membuat kelas ini sendiri dan menggunakannya dengan cara yang persis sama dengan kelas-kelas di atas.Artinya. Salah satu fakta yang menyedihkan tentang Java adalah ternyata Java tidak memiliki kelas untuk membaca data dalam bentuk yang bisa dibaca oleh manusia. Kelas PrintWriter. untuk membungkus baskomByte dalam baskomData.io memiliki kelas DataInputStream. writeInt(int x) untuk menulis nilai int. . maka DataOutputStream baskomData = new DataOutputStream(baskomByte). meskipun data kita tulis pada satu komputer dan data dibaca pada komputer jenis lain dengan sistem operasi berbeda. Dan juga kita bisa membungkus objek bertipe OutputStream atau turunannya ke dalam aliran DataOutputStream sehingga kita bisa menggunakan metode yang lebih kompleks. Pertanyaannya bagaimana kita melakukan baca tulis suatu objek? Mungkin secara tradisional kita akan membuat fungsi sendiri untuk memformat objek kita menjadi bentuk tertentu. kita harus bisa membaca data yang diserialisasi ini sesuai dengan format yang digunakan pada saat objek ini diserialisasi. Pada inputnya. Akan tetapi untuk ukuran objek yang besar. hal ini tidak mudah. java. pekerjaan semacam ini mungkin bukan masalah besar. Proses ini disebut serialisasi (serializing) objek. dan seterusnya. Untuk objek kecil. Metode di dalam DataInputStream untuk membaca data biner bisa menggunakan readDouble(). Dalam hal ini Java tidak memiliki kelas kebalikan dari PrintWriter sebagaimana DataOutputStream dan DataInputStream. OutputStream hanya berisi metode dasar untuk menulis byte. Data yang ditulis oleh DataOutputStream dijamin untuk bisa dibaca kembali oleh DataInputStream. readInt() dan seterusnya. yaitu dengan menggunakan ObjectInputStream dan ObjectOutputStream. Kita bisa membungkus objek bertipe InputStream atau turunannya ke dalam objek bertipe DataInputStream. jika baskomByte adalah variabel bertipe OutputStream. sedangkan DataOutputStream memiliki metode writeDouble(double x) untuk menulis nilai double. Kompatibilitas data biner pada Java adalah salah satu keunggulan Java untuk bisa dijalakan pada beragam platform. Kelas-kelas ini adalah kelas turunan dari InputStream dan OutputStream yang bisa digunakan untuk membaca dan menulis objek yang sudah diserialisasi. DataInputStream. misalnya urutan tipe primitif dalam bentuk biner atau karakter kemudian disimpan dalam file atau dikirim melalui jaringan. Untuk mengambil data dari aliran. dan DataOutputStream memungkinkan kita untuk melakukan input dan output semua tipe data primitif pada Java.

ObjectInputStream dan ObjectOutputStream hanya bekerja untuk objek yang mengimplementasikan interface yang bernama Serializable. Mengimplementasi konsep "piping". Artinya kita bisa melakukan input dan output objek pada aliran byte apa saja. Bisa digunakan untuk multi-threading Menggabungkan dua atau lebih InputStream menjadi satu InputStream Objek PipedOutputStream Dua atau lebih objek bertipe InputStream atau kontainer bertipe Enumeration yang berisi InputStream yang akan .ObjectInputStream dan ObjectOutputStream adalah kelas yang bisa dibungkus oleh kelas InputStream dan OutputStream lain. Metde untuk objek I/O adalah readObject() yang tersedia pada ObjectInputStream dan writeObject(Object obj) yang tersedia dalam ObjectOutputStream. karena interface Serializable tidak mempunyai metode apaapa. Ingat bahwa readObject() mengembalikan nilai bertipe Object yang artinya harus di-type cast ke tipe sesungguhnya. Interface ini ada hanya sebagai penanda untuk kompiler supaya kompiler tahu bahwa objek ini digunakan untuk baca tulis ke suatu media. atau objek bertipe File atau dalam file FileDescriptor PipedInputStream SequenceInputStream Menghasilkan data yang ditulis oleh PipedOutputStream. Berbagai Jenis InputStream dan OutputStream InputStream Beberapa kelas turunan dari InputStream dapat dirangkum dalam tabel di bawah ini : Argumen yang dibutuhkan Kelas Kegunaan untuk membuat objek Menggunakan buffer pada Buffer yang akan digunakan ByteArrayInputStream memori sebagai aliran input sebagai aliran input Suatu String (di dalamnya StringBufferInputStream Mengubah string menjadi sebenarnya menggunakan InputStream StringBuffer) Untuk membaca informasi dari String yang berupa nama suatu FileInputStream file. Lbih jauh semua variabel instansi pada objek harus bisa diserialisasi. termasuk semua komponen kelas Swing dan AWT. Yang perlu kita lakukan adalah menambahkan "implements Serializable" pada definisi kelas. Banyak kelas standar Java yang telah dideklarasikan untuk bisa diserialisasi. Keduanya bisa melemparkan IOException. Artinya komponen GUI pun bisa disimpan dan dibaca dari dalam perangkat I/O menggunakan ObjectInputStream dan ObjectOutputStream.

Kelas FilterInputStream sendiri terdiri dari beberapa jenis. akan tetapi tidak mengubah bagaimana I/O itu sendiri bekerja. disiapkan String yang berupa nama FileOutputStream Untuk menulis informasi ke dalam file suatu file. Kenapa dekorator? Karena kelas-kelas ini hanya memberikan fungsionalitas tambahan. kemudian membacanya kembali tanpa harus diformat sendiri Digunakan untuk menghindari pembacaan InputStream dengan langsung dari media secara fisik setiap kali kemungkinan BufferedInputStream perintah read() diberikan. Seperti disebutkan sebelumnya. atau objek bertipe File atau FileDescriptor PipedOutputStream Informasi yang kita kirim di aliran output Objek PipedInputStream ini akan berakhir pada objek bertipe . Semua Opsional untuk memberikan ByteArrayOutputStream data yang kita kirim akan disimpan di besar buffer yang akan memori ini. LineNumberInputStream Kita bisa menggunakan perintah InputStream getLineNumber() dan setLineNumber(int) Memiliki satu byte buffer sehingga kita bisa PushBackInputStream InputStream meletakkan kembali karakter yang sudah diambil (dibaca) FilterInputStream OutputStream Beberapa kelas turunan dari OutputStream dapat dirangkum dalam tabel di bawah ini : Argumen yang dibutuhkan Kelas Kegunaan untuk membuat objek Membuat buffer dalam memori. bahwa kelas dasar InputStream dan OutputStream hanya memiliki metode-metode paling sederhana.digabungkan FilterInputStream Kelas abstrak yang merupakan interface dari beberapa kelas bantu untuk menggunakan InputStream lain adalah lapisan di atas InputStream yang berguna untuk memberi landasan pada kelas-kelas dekorator di atas. yang bisa dirangkum dalam tabel berikut ini : Argumen yang Kelas Kegunaan dibutuhkan untuk membuat objek Digunakan bersama-sama dengan DataOutputStream sehingga kita bisa menulis DataInputStream InputStream tipe data primitif. Kelas-kelas ini memperbanyak metode baca/tulis untuk kemudahan pemrograman. Atau dengan kata menentukan besar lain "gunakan buffer" untuk baca tulis buffer sendiri Mencatat nomor baris dalam InputStream.

Data karakter yang bisa dibaca manusial dapat dibaca dari file dengan menggunakan objek dari kelas FileReader yang merupakan kelas turunan Reader. Bisa digunakan untuk multi-threading Kelas abstrak yang merupakan interface dari beberapa kelas bantu untuk menggunakan OutputStream lain. Digunakan untuk menghindari penulisan langsung dari media secara fisik setiap kali perintah write() diberikan. yang bisa dirangkum dalam tabel berikut ini : Argumen yang Kelas Kegunaan dibutuhkan untuk membuat objek Digunakan bersama-sama dengan DataInputStream sehingga kita bisa DataOutputStream OutputStream menulis tipe data primitif. FilterOutputStream Mengimplementasi konsep "piping". sehingga data yang ditulis bisa baru ditulis. Kelas FilterOutputStream sendiri terdiri dari beberapa jenis. Direktori bisa terdiri dari direktori lain atau file lain. DataOutputStream hanya tambahan opsi boolean menangani bagaimana data disimpan untuk memerintahkan PrintStream sehingga bisa diambil kembali. File disusun dalam direktori (atau sering juga disebut folder). buffer akan dikosongkan PrintStream lebih berkonsentrasi pada (flush) setiap kali baris "tampilan". dan lain-lain. kemungkinan menentukan Kita bisa menggunakan perintah flush() besar buffer sendiri untuk mengosongkan buffer dan mengirimkan hasilnya ke media fisik. disket atau CD-ROM. komputer menggunakan file. . dibaca dengan baik. Untuk tempat penyimpanan yang lebih lama. Nama direktori dan file digunakan untuk mencari suatu file dalam komputer. yaitu kumpulan data yang disimpan dalam hard disk. Dalam Java. USB stick. Atau dengan OutputStream dengan BufferedOutputStream kata lain "gunakan buffer" untuk baca tulis. kemudian membacanya kembali tanpa harus diformat sendiri Untuk mengeluarkan output yang sudah OutputStream dengan diformat. Program dapat membaca data dari file yang sudah ada.PipedInputStream. File Data dan program pada memori komputer hanya bisa bertahan selama komputer itu nyala. input dan output seperti ini bisa menggunakan aliran (stream). Program juga bisa membuat file baru atau menulis data ke dalam file yang sudah ada.

Untuk mencegah hal seperti itu. Untuk membaca atau menyimpan suatu file dalam format mesin. yaitu dengan mengunjungi halaman web pada browser kita. dan kita ingin membuat program untuk membaca data pada file tersebut. } . Jika applet tersebut bisa digunakan untuk mengakses file pada komputer kita.txt". anggap kita memiliki file bernama "data. Mengakses file adalah salah satu hal yang dilarang.io. maka orang bisa membuat applet untuk menghapus semua file dalam komputer yang mendownloadnya. ada beberapa hal di mana applet yang didownload tidak bisa lakukan. maka variabel tersebut hanya bisa // dilihat di dalam blok try. Milsanya. dan kita tidak bisa // menggunakannya lagi di bagian program lain FileReader data. Akan tetapi program desktop bisa memiliki akses ke file kita seperti program-program lainnya. Jenis pengecualian seperti ini membutuhkan penanganan wajib. kelas I/O-nya adalah FileInputStream dan FileOutputStream. Konstruktor ini akan melemparkan pengecualian bertipe FileNotFoundException jika file tersebut tidak ditemukan. sehingga kita harus memanggil konstruktor di dalam pernyataan try atau menambahkan pernyataan throw di kepala subrutin yang menjalankan konstruktor tersebut.txt"). try { // buat aliran input data = new FileReader("data. Kita bisa mendownload dan menjalankan applet. Perlu dicatat bahwa applet yang didownload dari suatu jaringan pada umumnya tidak bisa mengakses file karena pertimbangan keamanan. Semua kelas ini didefinisikan dalam paket java. Kita bisa menggunakan pernyataan berikut untuk membaca aliran input dari file tersebut : // (Mendeklarasikan variabel sebelum pernyataan try // jika tidak. kemudian membuat aliran input yang bisa digunakan untuk membaca file tersebut. Kelas FileReader memiliki konstruktor yang mengambil nama file sebagai parameternya.Data bisa ditulis dalam bentuk yang bisa dibaca manusia dengan menggunakan FileWriter yang merupakan kelas turunan dari Writer. Program desktop bisa melakukan akses file yang dijelaskan pada bagian ini.

} catch (FileNotFoundException e) { . Untuk menyimpan data tidaklah lebih sulit dari ini. kita bisa gunakan perintah Double.dat"..dat")). hampir semua kesalahan yang terjadi pada saat operasi input/output dapat ditangkap dengan pernyataan catch yang menangani IOException.. Untuk membuat BufferedReader untuk membaca file bernama "data. } catch (IOException e) { . Misalnya. Tapi karena FileReader hanya memiliki metode input primitif dari standar kelas Reader. Begitu kita berhasil membuat FileReader. misalnya BufferedReader atau kelas pembungkus lain. Kita bisa membuat objek bertipe FileWriter. Sehingga apabila satu data ditulis dalam urutan per baris..dat"))..catch di atas. Dan kemudian kita mungkin ingin membungkus aliran output ini dalam objek PrintWriter. try { data = new BufferedReader(new FileReader("data.dat".parseDouble(string) atau Integer. // tangani pengecualian } BufferedReader memiliki metode bantu untuk mengambil data per baris dengan perintah readline(). kita mungkin akan perlu membungkusnya dalam objek lain.. // lakukan sesuatu untuk menangani kesalahan } Kelas FileNotFoundException merupakan kelas turunan dari IOException..parseInt(string) untuk mengubahnya menjadi double atau int. kita bisa mulai membacanya. Secara umum. kita bisa menggunakan : PrintWriter result.catch (FileNotFoundException e) { . kita ingin menyimpan data ke file yang bernama "hasil. try { keluaran = new PrintWriter(new FileWriter("hasil. sehingga kita bisa menangkap IOException pada pernyataan try. kita bisa gunakan : TextReader data.

maka isinya akan dihapus dan diganti dengan data yang ditulis oleh program kita. // tangani pengecualian } Jika tidak ada file bernama "hasil. berikut ini adalah program yang akan membaca angka dari file bernama "data.*. Setelah file telah ditutup. (Perlu dicatat bahwa penutupan file juga bisa melemparkan pengecualian IOException yang wajib ditangani. maka file baru akan dibuat. maka kita tidak mungkin lagi membaca atau menulis data dari atau ke file tersebut. Jika file sudah ada. sebaiknya anda menutup file tersebut.dat". import java. Kita bisa menutup file dengan menggunakan metode close() pada aliran tersebut.. public class BalikFile { /** * @param args */ public static void main(String[] args) { . dan kemudian menuliskannya kembali dalam urutan terbalik ke dalam file yang bernama "hasil. Penanganan pengecualian digunakan untuk mengecek apakah ada masalah di tengah operasi. sistem operasi akan menutup file secara otomatis setelah program selesai dijalankan atau objek aliran file diambil oleh pemulung memori... Pengecualian IOException bisa terjadi jika. Meskipun mungkin tidak begitu berguna untuk aplikasi sungguhan.dat".dat". Dalam file tersebut hanya akan ada satu angka untuk setiap barisnya dan diasumsikan tidak ada lebih dari 1000 angka sekaligus. Kita harus membukanya kembali. sehingga sistem operasi menolak program kita untuk menulisnya pada saat yang sama. akan tetapi program ini mendemonstrasikan bagaimana menggunakan operasi baca tulis sederhana pada file. Sebagai contoh komplit. atau mengatakan kepada sistem operasi bahwa kita telah selesai menggunakan file itu (Jika kita lupa. misalnya.io. package balikfile. file tersebut sedang dibaca oleh program lain. akan tetapi PrintWriter menangani pengecualian tersebut secara otomatis sehingga kita tidak perlu menanganinya lagi). Setelah kita selesai menggunakan file. akan tetapi akan sangat baik jika kita menutup file secara manual untuk menghindari kemungkinan lainnya).

println("Tidak bisa menemukan data.dat")). // Aliran input karakter untuk membaca data PrintWriter hasil.println(e. // Banyaknya angka yg disimpan dlm array try { // Buat aliran input data = new BufferedReader(new FileReader("data. System. // akhiri program } try { // Membuat aliran output hasil = new PrintWriter(new FileWriter("hasil.toString()). // Tutup file input } catch (IOException f) { .dat")). try { data.close(). return. } catch (FileNotFoundException e) { System.dat!"). // Aliran output karakter untuk menulis data // Array untuk menampung semua angka dari dalam file double[] angka = new double[1000]. } catch (IOException e) { System.out.BufferedReader data.out.println("Tidak bisa membuka hasil.dat!"). int banyakAngka.out.

readLine()) != null) { // baca hingga habis angka[banyakAngka] = Double. // variabel untuk menyimpan satu baris teks try { // Baca data dari file input banyakAngka = 0. String baris = null. while ((baris = data.out. } .dat"). banyakAngka++.out.println("Selesai!"). i--) hasil.println(angka[i]).out.println("Tidak bisa menutup data. } catch (IOException e) { // Ada masalah dengan pembacaan/penulisan file System.System. i >= 0. } // End the program.parseDouble(baris). System.println("Kesalahan baca/tulis"). } return. } // Tulis hasilnya dalam urutan terbalik for (int i = banyakAngka-1.

// Tutup file input } catch (IOException e) { System.out.getMessage())."). System.close(). // Tutup file output } } } Berikut ini adalah program lengkapnya yang bisa diimport ke dalam Eclipse beserta contoh file data. } catch (IndexOutOfBoundsException e) { // Tidak boleh meletakkan 1000 angka dalam file System.out.dat yang bisa Anda double-click untuk melihat hasilnya .println("Terlalu banyak angka.out.catch (NumberFormatException e) { // Ada masalah dengan format angka dalam file System.println("Tidak bisa menutup data.out.close(). } finally { // Akhiri dengan menutup semua file apapun yang terjadi try { data.println("Penulisan dihentikan.dat").dat. Setelah selesai dijalankan file baru akan dibuat hasil. } hasil.println("Kesalahan format: " + e.").

Mengacu pada file bernama data. maka ini adalah nama path absolut pada Macintosh OS 9 • contoh/data.dat pada direktori aktif.dat dan pada Macintosh menjadi contoh:data. Direktori. ada dua jenis nama path. Direktori juga dianggap Java sebagai File.Nama File.dat. Lebih tepatnya. Misalnya " data.dat -. Untuk menunjuk pada sebuah file. yaitu nama path absolut dan nama path relatif. Sayangnya. dan Kelas File Topik tentang nama file sebenarnya lebih kompleks daripada yang telah kita bahas. Untuk memperjelas lagi.dat disimpan pada direktori yang sama dengan direktori utama pada proyek balikfile.dat -.dat -. yaitu file data. Sedangkan nama path relatif adalah nama file yang dihitung mulai dari direktori aktifnya. Nama file sederhana seperti "data. Objek bertipe kelas ini melambangkan suatu file.Misalnya "Hard Drive" adalah nama dari drivenya. Pada program di bagian sebelumnya.dat di direktori yang ditunjuk. Untuk mencegah berbagai masalah yang mungkin muncul karena beragam sistem ini. hasil. atau juga disebut direktori kerja). Pada Windows.Nama path absolut pada sistem operasi LINUX atau UNIX. Nama yang ditunjuk belum tentu ada. Java memiliki kelas bernama java. nama path relatifnya menjadi contoh\data. • • . Nama path absolut memiliki informasi lengkap dari akar direktorinya. kita harus memberikan bukan hanya nama file. sintaks untuk nama path dan file bervariasi dari satu sistem ke sistem lain. misalnya "C:\workspace\balikfile\data.dat -. sehingga File juga melambangkan nama direktori sekaligus nama file.io. objek bertipe File melambangkan nama file. File yang tidak diletakkan pada direktori kerja harus diberikan nama "path". • C:\lyracc\java\contoh\data.dat adalah file dalam direktori tersebut. atau nama lengkap termasuk nama direktorinya.dat". /home/lyracc/java/contoh/data.dat" atau "hasil.File.dat -.pada komputer apapun.Nama path absolut pada DOS atau Windows • Hard Drive:java:contoh:data. bukan file itu sendiri.nama path relatif pada LINUX atau UNIX. dan data.dat" diambil dengan mengacu pada direktori sekarang (current directory. "contoh" adalah nama direktori yang terdapat pada direktori aktif. tapi juga nama direktori di mana file tersebut disimpan.

*. maka fungsi ini mengembalikan array bertipe String[] yang berisi nama-nama file pada direktori tersebut.exists() -. • file. Nama tersebut bisa nama sederhana.delete() -. public class DaftarDirektori { /* Program ini mengembalikan isi suatu direktori * User memasukkan direktori yang ingin dilihat * Jika direktori tidak ada. atau tidak ada file dengan nama tersebut. maka pesan kesalahan * akan ditulis dan program akan berhenti */ public static void main(String[] args) { String namaDirektori = null.isDirectory() -.Objek File memiliki konstruktor new File(String) yang akan membuat objek File dari namanya.mengembalikan nilai boolean yang mengembalikan true jika objek File adalah suatu direktori. Kita bisa menggunakan perintah ini misalnya untuk mencegah menulis file yang sama ketika kita membuka objek FileWriter baru. Berikut ini adalah contoh program yang menulis isi file di dalam direktori yang diinput dari user : package daftardirektori. atau nama path absolut.String).mengembalikan nilai boolean. dan parameter kedua adalah nama filenya.list() -.menghapus file jika ada • file. Objek File memiliki beberapa metode instansi. • import java. dan false jika File adalah file biasa. Jika tidak. • file.jika objek File adalah suatu direktori. Konstruktor lain memiliki konstruktor new File(File. di mana parameter pertama adalah direktori di mana file tersebut berada. berikut ini adalah beberapa metodenya : file. yang jika true maka file tersebut ada.io. Misalnya new File("data.dat") membuat objek File dari file bernama data. // Nama direktori dari user . maka kembaliannya adalah null. Misalnya file adalah variabel bertipe File.dat di direktori aktif. nama path relatif.

} direktori = new File(namaDirektori).print("Masukkan nama direktori : "). else System.println("Files dalam direktori \"" + direktori + "\":").println("Ini bukan direktori. i < isiFile. // objek File yang mengacu pada direktori // Array berisi file pada direktori // buat objek baru untuk mengambil input BufferedReader br = new BufferedReader(new InputStreamReader(System.length.println("Kesalahan IO terjadi").println("Tidak ada direktori ini!").readLine().File direktori. try { namaDirektori = br. String[] isiFile.out.isDirectory() == false) { if (direktori. for (int i = 0.out. } else { isiFile = direktori. System.out. } catch(IOException ioe) { System.exists() == false) System. if (direktori.in)). System.out.out. System. i++) .exit(1).list().").

maka kita bisa membuat FileReader untuk melakukannya dengan menggunakan new FileReader(file). File lagu atau video misalnya berisi deretan byte yang merupakan representasi digital dari lagu atau video tersebut.System. Karena program harus bisa mengkopi file jenis apapun. . Ini adalah hasil keluarannya : Semua kelas yang digunakan untuk memaca dan menulis data dari dan ke dalam file memiliki konstruktor yang bisa mengambil objek File sebagai parameternya. Misalnya. dan sistem operasi manapun memiliki perintah atau cara untuk melakukannya. dan kita ingin mengambil karakter dari file tersebut. Mengkopi File Mengkopi suatu file adalah operasi biasa.out. } } } Berikut ini adalah program lengkapnya yang bisa diimport ke dalam Eclipse. kita tidak bisa menganggap data di dalam file adalah data yang bisa dibaca manusia. jika file adalah variabel bertipe File.println(" " + isiFile[i]). Akan tetapi kita juga bisa membuat program Java untuk melakukannya.

pada konsol Windows. while((byteTerbaca = sumber.dat akhir. int byteTerbaca. Program yang akan kita buat menerima input dari baris perintah. maka byteTerbaca = sumber. Tambahan parameter pada konsol ini disebut argumen baris perintah. Ingat bagaimana "biasanya" subrutin main() dideklarasikan sebagai public static void main(String[] args). kemudian diletakkan dalam variabel byteTerbaca. berarti tidak ada lagi data yang bisa diambil dari dalam sumber.dat. Jika sumber adalah variabel bertipe InputStream. kita bisa memanggilnya dengan "java KopiFile awal. akan tetapi kita membutuhkan tempat sementara di mana data tersebut akan ditempatkan sebelum data tersebut ditulis kembali pada OutputStream. byteTerbaca). Kemudian program akan mengecek apakah kedua parameter tersebut berisi nama file dengan benar. Argumen baris perintah ini bisa juga digunakan dalam program Java. Program yang kita buat akan mengkopi beberapa byte sekaligus dari InputStream ke OutputStream.dat ke file bernama akhir.dat sedangkan args[1] akan berisi akhir. Begitu juga jika kopi adalah keluaran yang bertipe OutputStream maka kopi. Sehingga secara umum perintah-perintah di atas dapat dirangkum menjadi : byte[] buffer = new byte[4096]. Dalam Java argumen baris perintah ini diisi dalam array String[] bernama args.read(buffer)) != -1) kopi. Pada program Java yang sudah dikompilasi. 0. misalnya 4096 byte (atau 4 kilo byte). yang kemudian dimasukkan sebagai parameter dalam subrutin main(). kita bisa menggunakan "copy awal. Tempat sementara tersebut disebut buffer yang merupakan array berukuran tertentu. args[0] akan berisi awal.write(buffer.read(buffer) akan mengisi penuh buffer. Misalnya. Jika hasilnya -1. 0. Perintah kopi-file pada sistem operasi baik DOS/Windows atau LINUX/UNIX menggunakan perintah pada konsol yang menambahkan file sumber dan file tujuannya.dat" untuk mengkopi file awal.dat akhir.write(buffer. Metode ini mengembalikan int yang merupakan berapa byte yang efektif diambil oleh sumber.dat. byteTerbaca) menulis deretan byte dari buffer dari posisi 0 hingga byteTerbaca ke aliran keluaran kopi.dat" jika KopiFile adalah nama kelas yang akan kita buat untuk mengkopi file. bukan Reader dan Writer yang hanya bisa menangani data yang bisa dibaca manusia.Oleh karena itu kita harus menggunakan InputStream dan OutputStream untuk melakukan operasi baca tulis yang bisa menangani data biner. Jika salah satu .

yaitu sumberFile dan tujuanFile if (args. import java. Program juga akan mengecek apakah akhir. String tujuanNamaFile = args[1]. File sumberFile = new File(sumberNamaFile).parameternya kosong. Berikut ini adalah listing lengkap program KopiFile.dat. yang bisa diunduh di sini dan diimport ke dalam Eclipse.length < 2) { System. jika tidak maka program akan dihentikan. return.println("Cara menjalankan program : " + "java KopiFile sumberFile tujuanFile"). .io. File kopiFile = new File(tujuanNamaFile).*. maka program akan menampilkan pesan kesalahan. } String sumberNamaFile = args[0]. Jika ya.out. maka operasi akan diteruskan.dat merupakan file yang sudah ada sebelumnya. public class KopiFile { /** * @param args */ public static void main(String[] args) { // Mengecek apakah argumen program cukup untuk meneruskan program // Dibutuhkan dua argumen. kemudian memberi pertanyaan kepada user apakah isi file ini ingin ditindih dengan isi file awal.

} // Di sini kita siap untuk mengkopi file // Buat aliran input dan output FileInputStream sumber = null.exit(1).println("Kesalahan IO terjadi"). kita akan tanyakan apakah file tujuan // akan ditimpa if (kopiFile.readLine(). try { sumber = new FileInputStream(sumberFile). } catch(IOException ioe) { System.out.// Jika kopi file sudah ada. String timpaFile = null.out.equalsIgnoreCase("t")) return.in)). System.exists()) { // buat objek baru untuk mengambil input BufferedReader br = new BufferedReader(new InputStreamReader(System. hentikan program if (timpaFile. } catch (FileNotFoundException e) { . try { timpaFile = br. System.print("Apakah Anda ingin menimpa " + tujuanNamaFile + " ? (y/t) "). } // jika jawabannya tidak.

} catch (IOException e) { System. } byte[] buffer = new byte[4096].println("Ada masalah di tengah pengkopian program"). return.out. berupa direktori " + "atau tidak bisa dibuka. try { while((byteTerbaca = sumber.write(buffer. program dihentikan!").println("File tujuan tidak valid atau tidak bisa ditulis. int byteTerbaca. return. } catch (FileNotFoundException e) { System. byteTerbaca). " + "program dihentikan!").out. } FileOutputStream kopi = null. return.out. .read(buffer)) != -1) kopi. } System.out.System.println("Kopi file selesai dijalankan!"). try { kopi = new FileOutputStream(tujuanNamaFile).println("File sumber tidak ada. 0.

karena tidak ada parameter yang diberikan. sedangkan bin adalah tempat dimana hasil kompilasi berada. maka tampilan kesalahan akan muncul. saya meletakkan semua proyek Eclipse pada c:\belajarjava.com\Kopi123.java ke c:\belajarjava. Di dalamnya seharusnya Anda akan menemui 2 direktori. src adalah tempat di mana kode sumber berada.} } Perlu diingat bahwa program ini tidak bisa dijalankan lewat Eclipse. Berikut screenshot hasil jalannya program. Misalnya pada komputer saya. Eclipse akan melakukan kompilasi secara otomatis. .java. Anda harus membuka konsol pada Windows dengan Start -> Run -> kemudian ketik cmd dan enter. Setelah itu pergi ke direktori tempat proyek Anda berada pada Eclipse. Di sini saya mengkopi file dari c:\belajarjava.com\KopiFile\src\KopiFile.com\KopiFile.lyracc.lyracc. Jika Anda mencoba menjalankan lewat Eclipse. Untuk menjalankan program. yaitu src dan bin.lyracc.

dan output di mana data bisa dikirim.net. yaitu berdasarkan ide suatu soket (socket). Konsep ini mempermudah pemahaman kita tentang pemrograman dalam jaringan. Jenis I/O kedua adalah melihat jaringan pada tingkatan yang lebih rendah. Pada Java. dan Server Contoh Pemrograman pada Jaringan URL dan URLConnection Kelas URL digunakan untuk merepresentasikan suatu sumber pada Web.URLConnection. Salah satu paket Java standar adalah java.net. karena ada dua komputer yang berbeda. Akan tetapi membuat koneksi jaringan antara dua komputer sedikit lebih rumit. yang masing-masing terhubung ke program yang dijalankan pada komputer lain. Java memiliki kelas java. kita bisa menggunakan aliran input dan output untuk melakukan komunikasi pada network. berdasarkan pada Web dan memberikan fasilitas komunikasi seperti halnya web browser ketika mendownload suatu halaman web untuk kemudian ditampilkan. Bagian ini akan memberikan pengenalan tentang kelas-kelas dasar jaringan.Socket untuk merepresentasikan suatu soket yang digunakan dalam komunikasi network. Alamat ini disebut "url" atau "universal resource locator". yang keduanya harus setuju membuka koneksi. Sedangkan URLConnection adalah koneksi network ke dokumen tadi. seperti halnya pada file.net. Dua jenis I/O network disediakan dalam paket ini. Semuanya menggunakan koneksi network yang sama dari satu kabel. yang unik (tidak bisa sama). yaitu masing-masing pada setiap komputer. Setiap sumber memiliki alamat. Kelas utama dalam jenis network seperti ini adalah java. jaringan (network) hanyalah salah satu jenis dari input di mana data bisa diambil. dan memiliki informasi yang cukup sehingga web browser bisa mencari sumber tersebut dan mengambilnya. Istilah "soket" mungkin mirip dengan colokan kabel data (misalnya) modem.Jaringan (network) Dalam pemrograman. . yang lebih tinggi tingkatannya. Suatu objek bertipe URL adalah lambang abstrak dari sebuah URL (Universal Resource Locator). Yang pertama. Paket ini memiliki beberapa kelas yang bisa digunakan untuk berkomunikasi melalui jaringan. Artinya program bisa memiliki beberapa soket dalam waktu yang sama.net. Soket digunakan oleh program untuk melakukan koneksi dengan program lain pada suatu jaringan. • • • URL dan URLConnection Soket. komunikasi harus dilakukan seirama sehingga data yang dikirimkan akan sampai ke komputer yang lain. akan tetapi ada beberapa hal lain yang harus diperhatikan sehingga pemrograman pada jaringan dapat berhasil dengan baik. Klien.URL dan java. Dan ketika data dikirimkan dari satu komputer ke komputer lain. akan tetapi penting untuk diingat bahwa soket adalah objek bertipe Socket. Komunikasi melalui network melibatkan dua soket. yaitu alamat web di mana dokumen HTML atau lainnya bisa ditemukan pada web. dan bagaimana hubungannya dengan aliran input dan ouput serta pengecualian.

Ada juga yang disebut url relatif. Metode getDocumentBase() pada kelas Applet mengembalikan objek bertipe URL. Dengan ini. Misalnya. URLConnection koneksi = url. kita bisa memerintahkan applet untuk kembali dan mengambil file lain yang disimpan di tempat yang sama. . "data. tersedia dua metode yang bisa digunakan untuk mengambil konteks URL. sehingga konstruktor di atas harus dipanggil dalam pernyataan try . Misalnya jika konteksnya adalah http://java. Misalnya : URL url = new URL(alamatURL). Objek URLConnection bisa digunakan untuk membuka InputStream untuk membaca halaman atau file pada alamat URL tersebut. Setelah kita memiliki objek URL yang benar. catch atau ditulis di dalam subrutin yang melempar pengecualian ini. maka kita bisa membuka URLConnection ke alamat tersebut.. Metode ini mengembalikan objek bertipe URLConnection.com/belajar/java-untuk-pemula/bab-i-pendahuluan". Suatu url biasanya berupa string. Kelas MalformedURLException merupakan kelas turunan dari IOException yang wajib ditangani.. URL relatif adalah lokasi suatu sumber relatif terhadap url lain. kita bisa memanggil openConnection() untuk membuka koneksi pada URL tersebut. mengembalikan URL yang merupakan lokasi di mana applet tersebut berada (belum tentu sama dengan lokasi HTML-nya). Konstruktur jenis kedua akan lebih nyaman digunakan untuk applet.lyracc. Konstruktornya memiliki bentuk seperti : public URL(String alamatURL) throws MalformedURLException dan public URL(URL konteks. Suatu objek bertipe URL bukan string sederhana. Objek URL ini adalah lokasi tempat halaman HTML yang berisi applet tersebut berada. Jika kita sudah memiliki objek bertipe URL. membuat URL baru yang merujuk pada file bernama data.txt"). akan tetapi dibangun dari kumpulan string yang membentuk suatu url. yaitu getCodeBase(). misalnya "http://java. Dalam applet.Suatu objek beritpe kelas URL melambangkan alamat tersebut.lyracc. String alamatRelatif) throws MalformedURLException Lihat bahwa kedua konstruktor akan melempar pengecualian bertipe MalformedURLException jika string yang diberikan bukan nama url legal. Objek URL juga bisa dibuat dari objek URL lain.lyracc. Metode lainnya. yaitu dengan menggunakan metode getInputStream().txt pada komputer yang sama dan pada direktori yang sama pada halaman web di mana applet tersebut sedang berjalan. dan string lain yang berisi relatif urlnya. yang biasanya disebut landasan (base) atau konteks (context) dari url relatif tersebut.openConnection().com/belajar/java-untuk-pemula/babi-pendahuluan. yang merupakan konteksnya.com/belajar/java-untuk-pemula/ maka url relatif dari "bab-i-pendahuluan" akan menunjuk pada http://java. URL url = new URL(getDocumentBase().

getInputStream(). yang mengembalikan String yang menjelaskan jenis informasi pada URL yang ditunjuk. Jenis dokumen bisa saja belum tersedia hingga aliran input berhasil dibuat. . "text/html". Hasilnya bisa bernilai null jika jenisnya belum diketahui. mengecek apakah jenisnya berupa teks.openConnection(). termasuk membungkusnya dalam aliran input jenis lain. seperti "text" atau "image". Jika InputStream berhasil dibuka. Metode openConnection() dan getInputStream dapat melempar pengecualian IOException. sehingga lebih baik menggunakan getContentType() setelah getInputStream() berhasil dilakukan. Beberapa operasi dalam subrutin ini mungkin melempar pengecualian. "image/gif". Mari kita lihat contoh singkat bagaimana membaca data dari suatu URL. Jika kita hanya tertarik pada data teks misalnya. kita hanya perlu menguji apakah hasil keluaran getContentType() dimulai dengan "text". Salah satu metode instansi yang berguna dalam kelas URLConnection adalah getContentType(). Kita akan menambahkan "throws Exception" di kepala subrutin untuk meneruskan penanganan pengecualian ini kepada program utama yang memanggil subrutin ini. atau tidak bisa ditentukan. static void bacaTeksDariURL( String alamatURL ) throws Exception { // Subrutin ini mencetak isi dari alamat URL yang // diberikan ke layar. Namanya adalah singkatan dari "Multipurpose Internet Mail Extensions". Membaca dari aliran ini tentunya juga bisa melemparkan pengecualian. (Jenis MIME pertama kali dimaksudkan untuk menjelaskan isi email. "image/jpeg". MIME digunakan secara umum untuk menjelaskan jenis suatu informasi atau file pada suatu sumber). misalnya "html" atau "gif".InputStream dataURL = connection. kemudian mengkopi hasilnya ke layar. Subrutin berikut akan membuka koneksi ke URL tertentu. misalnya "text/plain". Semua jenis MIME terdiri dari dua bagian. dan ambil aliran input * untuk membaca data dari URL. kita bisa menggunakannya dengan cara biasa. URLConnection koneksi = url. yaitu bagian umum. dan banyak lagi lainnya. */ URL url = new URL(alamatURL). Kini. dan bagian khususnya. String yang dikembalikan oleh getContentType() ditulis dalam format yang disebut MIME. misalnya BufferedReader. Semua kesalahan akan ditangani // oleh program yang memanggil subrutin ini /* Buka koneksi ke URL.

data . Klien.InputStream dataURL = koneksi.getContentType(). ada lagi protokol komunikasi yang lebih sederhana yang disebut dengan UDP yang bisa digunakan menggantikan TCP pada beberapa aplikasi. UDP juga didukung Java. Setelah terhubung. masing-masing program harus membuat soket. yang kemudian soket-soket tersebut harus terhubung satu sama lain. Di sana. System. Agar dua program dapat berkomunikasi menggunakan TCP/IP.startsWith("text") == false) throw new Exception("URL tidak bertipe teks.getInputStream()."). Data yang ditulis oleh suatu program di aliran outputnya akan dikirim ke komputer lain. (Sebenarnya. /* Kopi karakter dari aliran input ke layar * hingga akhir file ditemukan (atau kesalahan ditemui) */ while (true) { int data = dataURL. akan tetapi kita akan membahas TCP/IP saja yang merupakan komunikasi dua arah yang handal digunakan pada beberapa komputer melalui jaringan). dan Server Komunikasi melalui internet dilakukan berdasarkan sepasang protokol yang dinamakan Internet Protocol dan Transmission Control Protocol. /* Cek apakah konten bertipe teks */ String jenisKonten = koneksi. } } // akhir bacaTeksDariURL() Soket. if (jenisKonten == null || jenisKonten.out.read().print((char)data). Setiap program harus memiliki aliran input dan outputnya masing-masing. komunikasi dapat dilakukan dengan menggunakan aliran input dan output seperti biasa. yang digabungkan menjadi TCP/IP. if (data < 0) break.

Kelas URL yang telah didiskusikan sebelumnya menggunakan soket klien di belakang layar untuk melakukan komunikasi jaringan yang dibutuhkan. Objek bertipe Socket melambangkan sisi lain dari suatu sambungan. atau bisa saja soket lain yang dibuat server untuk menangani permintaan dari klien. maka soket tersebut tidak berhenti mendengar. dan soket yang digunakan disebut soket klien. Program yang membuat soket pendengar. Pada komunikasi jaringan. program server dapat memberikan koneksi kepada beberapa klien pada waktu yang sama. soket ini akan merespon. Idenya adalah suatu server di suatu tempat pada network sedang menunggu permintaan sambungan dari suatu klien. Untuk mengimplementasikan koneksi TCP/IP. soket tersebut akan terus mendengar jika ada koneksi klien lain pada saat yang sama. Dalam aplikasi dunia nyata. paket java. dan meresponnya dengan mengirimkan isi file tersebut melalui network ke objek URL tadi. dan klien mendapatkan layanan dengan cara menyambungkannya pada server. Server dianggap sebagai sesuatu yang memberikan layanan.tersebut akan diisi pada aliran input program tersebut. program lain membuat soket yang mengirim permintaan sambungan ke soket pendengar tadi. Ketika soket pendengar menerima permintaan sambungan dari soket lain. maka masing-masing program akan bisa membuat aliran input dan aliran output untuk koneksi ini. Begitu komunikasi terjadi. dan soketnya disebut soket server. dan membuat Socket untuk melakukan koneksi yang sesungguhnya) . Dengan cara ini server bisa membuat beberapa soket dan menangani beberapa koneksi sekaligus. Setelah mengirimkan data. Dalam hal ini. membaca permintaan objek tersebut.net menyediakan dua kelas. yaitu ServerSocket dan Socket. Ketika suatu klien terhubung pada soket pendengar. Program yang menghubungi server disebut klien (client). ini disebut model klien/server. server akan memutuskan koneksi ini. juga sering disebut server. ia hanya bertugas untuk mendengarkan permintaan sambungan. Di sisi lain di komputer lain. Soket yang sedang menunggu ini disebut sedang "mendengar" (listening) suatu koneksi. (Suatu ServerSocket sendiri tidak berpartisipasi langsung pada koneksi itu sendiri. Akan tetapi. yang bisa berarti soket klien. misalnya permintaan file di alamat tertentu. Bagian tersulitnya adalah bagaimana membuat koneksi antar komputer tersebut. sehingga komunikasi akan terjadi. Objek bertipe ServerSocket melambangkan soket pendengar yang menunggu permintaan sambungan dari klien. Di sisi lainnya adalah program server yang menerima permintaan sambungan dari objek URL. suatu program harus membuat soket yang menunggu secara pasif hingga koneksi lain dari soket lain di komputer lain datang. Pertama-tama. maka pada dasarnya program tersebut membaca data yang dikirim oleh program lain. dua soket akan digunakan. Komunikasi akan terus terjadi hingga salah satu program menutup (close) koneksi. Ketika program tadi membaca aliran inputnya.

soket sebenarnya merupakan kombinasi antara alamat IP dan nomor port. kita sebaiknya menggunakan port benomor lebih besar dari 1024). Suatu server tidak hanya mendengar koneksi saja.Untuk menggunakan Socket dan ServerSocket. dan misalnya kita telah menulis metode baru beriLayanan(Socket) untuk menangani komunikasi dengan suatu klien. while (true) { .google. Jika kita membuat program server sendiri. dan mengembalikan objek Socket yang bisa digunakan untuk berkomunikasi dengan klien.com atau www. Maka bentuk sederhana dari program server adalah sebagai berikut : try { ServerSocket server = new ServerSocket(1728). ia tidak akan mengembalikan hasilnya sebelum permintaan sambungan diterima (atau suatu kesalahan terjadi). kita harus memberikan nomor port yang akan didengar oleh server.1). maka thread yang memanggil metode tersebut tidak bisa berbuat apa-apa. Komputer juga bisa memiliki nama domain seperti www. layanan internet lain juga memiliki nomor port standar. ia akan mulai mendengarkan permintaan sambungan. Metode accept() dalam kelas ServerSocket akan menerima permintaan tersebut. kita harus tahu tentang alamat Internet. Program klien harus bisa menentukan komputer mana yang akan berkomunikasi dengannya. akan tetapi ia mendengar koneksi dari port tertentu. (Nomor port standar adalah nomor di bawah 1024. (Ketika suatu metode diblokade. Agar bisa bekerja seperti ini. Klien yang ingin berkomunikasi dengan server harus mengetahui alamat Internet komputer beserta nomor port di mana server tersebut mendengarkan permintaan sambungan. misalnya. Metode accept() memiliki bentuk seperti public Socket accept() throws IOException Ketika kita memanggil metode accept(). kemudian mempersiapkan sambungan dengan klien. Suatu komputer bisa memiliki beberapa program untuk melakukan komunikasi network secara bersamaan. atau satu program mungkin berkomunikasi dengan beberapa komputer sekaligus. Server web. Metode ini disebut "diblokade" ketika menunggu koneksi. Akan tetapi thread lain di program yang sama masih bisa berjalan). ServerSocket tersebut akan terus mendengar koneksi hingga ia ditutup menggunakan metode close() atau hingga terjadi kesalahan. Konstruktornya memiliki bentuk seperti public ServerSocket(int port) throws IOException Setelah ServerSocket berhasil dijalankan. Misalnya kita akan membuat server yang akan mendengarkan port 1728. Ketika kita membuat objek bertipe ServerSocket.yahoo.com. Nomor port hanya merupakan bilangan bulat 16-bit (dari 0 hingga 216 . Setiap komputer pada internet memiliki alamat IP yang merupakan alamat unik setiap komputer di dalam internet. pada umumnya mendengarkan koneksi pada port 80.

beriLayanan(koneksi).port). kita bisa menggunakan metode getInputStream() dan getOutputStream() pada Socket untuk mengambil aliran input dan output yang bisa digunakan untuk komunikasi antara dua komputer. } Di sisi klien. out = koneksi.out.getInputStream().accept(). // port adalah port dimana server mendengarkan koneksi. in = koneksi. int port) { // namaKomputer bisa berupa alamat IP atau nama domain // dari komputer yang bertindak sebagai server. Setelah koneksi tersambung. Konstruktor akan memblokadi dirinya hingga koneksi tersambung atau hingga terjadi kesalahan. OutputStream out. try { koneksi = new Socket(namaKomputer. . InputStream in.getOutputStream(). Socket koneksi. Berikut ini adalah kerangka untuk melakukan koneksi klien : void koneksiKlien(String namaKomputer. } } catch (IOException e) { System. Untuk melakukan koneksi ke server pada suatu alamat dan port tertentu. int port) throws IOException Parameter pertama bisa berupa alamat IP atau nama domain. kita bisa menggunakan konstruktor public Socket(String komputer. // misalnya 1728. soket klien dibuat dengan menggunakan konstruktor pada kelas Socket.println("Server dimatikan dengan pesan kesalahan: " + e).Socket koneksi = server.

untuk membuat program tangguh yang bisa menangani segala permasalahan dalam jaringan yang kurang handal atau karena kesalahan manusia misalnya.close(). Yang kita bahas di sini semoga berguna sebagai pengantar untuk membawa Anda lebih jauh mencari tahu tentang pemrograman dengan jaringan. dengan kesalahan : " + e). bisa juga bergantung pada server untuk // memutuskan sambungan) } catch (IOException e) { } } // akhir koneksiKlien() Membuat komukasi melalui jaringan terlihat lebih mudah dari yang sebenarnya. adalah hal yang tidak mudah. mungkin perintah di atas cukup untuk digunakan. Jika jaringan yang kita gunakan benar-benar handal. Teks yang dikirim oleh server adalah tanggal dan waktu saat ini di komputer di mana server dijalankan. membaca satu baris teks dari server. Klien melakukan koneksi dengan server. Pengalaman yang bisa membawa kita menjadi programmer jaringan yang lebih baik dan lebih komplet. // Gunakan aliran in dan out untuk berkomunikasi dengan server . // (Atau. } .out. . . yaitu klien sederhana dan servernya. Akan tetapi.println( "Usah melakukan sambungan gagal. kemudian menampilkan teks ini pada layar.} catch (IOException e) { System. try { koneksi. return. Contoh Pemrograman pada Jaringan Contoh ini melibatkan dua program.

// Nama komputer yang akan disambungkan Socket koneksi.io. Nomor port antara 1 hingga 1024 hanya digunakan oleh layanan standar dan seharusnya tidak digunakan untuk server lainnya. Nomor port ini bisa berapapun di antara 1025 hingga 65535.*.length > 0) komputer = args[0]. /** * @param args */ public static void main(String[] args) { String komputer. Misalnya jika server dijalankan pada komputer kita sendiri. else { . public class KlienTanggal { static final int PORT_PENDENGAR = 32007. // Soket untuk berkomunikasi dengan // komputer tersebut Reader masuk. kita bisa memanggilnya dengan "java KlienTanggal localhost". import java. asalkan klien dan servernya menggunakan port yang sama. import java.Untuk membuka koneksi.*. // Aliran untuk membaca data dari koneksi /* Ambil nama komputer dari baris perintah */ if (args. Server akan mendengarkan pada port bernomor 32007.net. Berikut ini adalah program klien lengkapnya. Nama komputer atau alamat IP di mana server dijalankan harus diberikan pada paramater baris perintah. klien harus tahu di komputer mana server dijalankan dan di port mana server tersebut mendengarkan permintaan sambungan.

kemudian baca dan tampilkan di layar */ try { koneksi = new Socket( komputer.out.println("Cara menggunakan : java KlienTanggal <server>"). while (true) { int ch = masuk.out. masuk.print( (char)ch ). return. PORT_PENDENGAR ). if (ch == -1 || ch == '\n' || ch == '\r') break. } catch (IOException e) { System.out. } System.out. } } } . masuk = new InputStreamReader( koneksi.println(). System.getInputStream() ).close().// Tidak ada nama komputer yang diberikan // Beri pesan kesalahan dan program selesai System.println("Kesalahan : " + e). } /* Buat koneksi.read().

Dalam subrutin itu. Jika akhir aliran telah dicapai. maka nilai -1 akan dikembalikan.0. public class ServerTanggal { . server akan memanggil subrutin lain untuk menangani koneksi tersebut.util. Setelah soket pendengar kita buat. Aliran yang digunakan adalah aliran sederhana Reader yang memiliki operasi input masuk.*.net. Kita bisa membuat program klien dan server pada komputer yang sama.read(). Agar program ini dapat berjalan tanpa kesalahan. Objek bertipe Date melambangkan tanggal dan waktu. tergantung dari jenis komputer di mana server tersebut berjalan. kemudian mengembalikan nomor kode Unicodenya.0. import java. Akhir baris ditandai dengan salah satu dari '\n' atau '\r' atau keduanya. maka program server harus dijalankan terlebih dahulu.1. import java. Ini akan menangkap pengecualian IOException yang mungkin terjadi ketika koneksi sedang dibuka atau ditutup atau sedang membaca karakter dari aliran input. Misalnya kita bisa membuat dua jendela konsol pada windows. Atau bisa juga menggunakan alamat "localhost" sebagai pengganti "127. Program ini akan berjalan terus menerus tanpa henti kecuali kita hentikan dengan paksa -.Date akan digunakan untuk mengambil tanggal saat ini. "new Date()" membuat objek yang melambangkan tanggal dan waktu ketika objek tersebut dibuat. sehingga perintah "java KlienTanggal 127. (Kelas standar java. Program ServerTanggal membuat ServerSocket untuk mendengarkan permintaan sambungan pada port 32007. Agar ini bisa berjalan. Perulangan while membaca karakter ini satu per satu hingga akhir aliran ditemui atau akhir baris ditemui.io.. Fungsi ini membaca satu per satu karakter dari aliran. Ketika koneksi diterima dari klien.Date.) Berikut ini adalah program server lengkapnya : import java.. pengecualian apapun yang terjadi akan ditangkap sehingga server tidak akan mati.1" artinya sama dengan memerintahkan program KlienTanggal untuk melakukan sambungan dengan server yang berjalan di komputer yang sama.misalnya dengan menekan tombol Ctrl-C di jendela konsol di mana server dijalankan.0. maka server akan masuk pada perulangan tak hingga di mana ia menerima dan mengolah permintaan sambungan. Subrutin akan membuat aliran PrintWriter untuk mengirim data melalui koneksi yang terjadi.1".0.*. Server akan menulis tanggal dan waktu sekarang pada aliran output ini. Program servernya kita namakan ServerTanggal. catch. kemudian menutup koneksi.0. kemudian menjalankan server di konsol yang satu dan menjalankan klien di server yang lain.Perhatikan bahwa semua komunikasi dengan server dilakukan dalam pernyataan try . Konstruktor standarnya.util.0. komputer lokal kita memiliki alamat 127.

. (Kesalahan yang terjadi ketika sedang berkomunikasi atau * mengirimkan tanggal akan ditangkap untuk mencegah server crash) */ try { pendengar = new ServerSocket(PORT_PENDENGAR). // Untuk berkomunikasi dengan sambungan yang masuk /* * Menerima dan mengolah sambungan selamanya. while (true) { koneksi = pendengar. System. atau hingga kesalahan * terjadi. // Mendengarkan sambungan yang masuk Socket koneksi. System.println("Maaf.println("Kesalahan : " + e)."). /** * @param args */ public static void main(String[] args) { ServerSocket pendengar.static final int PORT_PENDENGAR = 32007.out. kirimTanggal(koneksi).out.println("Mendengarkan pada port " + PORT_PENDENGAR).accept().out. server telah mati. } } catch (Exception e) { System.

Kemudian ia akan berjalan di latar belakang.toString()). klien. komputer yang . try { System. program tersebut seharusnya dijalankan sebagai daemon.close(). Date sekarang = new Date().out.out. // Pastikan data telah terkirim! klien. Ambil aliran keluaran untuk melakukan sambungan.println("Sambungan dari " + klien. // kirim tanggal saat ini dan tutup sambungan. maka ia akan diam menunggu datangnya permintaan sambungan dan melaporkannya apabila permintaan telah masuk.toString()).return. keluar. keluar. Agar layanan ServerTanggal tetap tersedia pada suatu komputer.println("Kesalahan : " + e). // Tanggal dan waktu saat ini PrintWriter keluar.println(sekarang. Komputer bisa dikonfigurasi untuk menjalankan daemon secara otomatis ketika komputer dinyalakan. } catch (Exception e) { System. // Aliran output untuk mengirim tanggal keluar = new PrintWriter(klien. meskipun komputer digunakan untuk hal lainnya.getOutputStream()).getInetAddress(). adalah soket yang telah terhubung dengan // program lain. } } } Jika kita jalankan ServerTanggal pada konsol. tidak peduli siapa yang menggunakan komputer itu.flush(). Daemon adalah program yang terus berjalan pada suatu komputer. } } static void kirimTanggal(Socket klien) { // Parameternya. Misalnya.

jalankan program server terlebih dahulu. Untuk menjalankan program di atas. seperti pada screen shot berikut ini : .menyediakan layanan Web menjalankan daemon yang mendengarkan permintaan sambungan untuk melihat halaman web dan meresponnya dengan mengirimkan isi halaman tersebut. program server memanggil keluar. Kemudian untuk menjalankan program klien. Metode flush() tersedia pada semua kelas aliran output. Atau bahkan masih ada data yang belum terkirim hingga soket ditutup. ada kemungkinan program akan mengumpulkan banyak data dan mengirimkan semuanya sekaligus. Mungkin dari segi efisiensi terlihat bagus. Dan program di atas dapat diunduh pada daftar sisipan di bawah. dari dalam konsol ketik "cd <nama_direktori_tempat_proyek_server_berada>\bin" (di screen shot di atas direktorinya berada di c:\belajarjava. Bagaimana menjalankan program sebagai daemon tidak akan kita bahas di sini. Untuk mengetahui di direktori mana proyek ini berada pada Eclpse Anda.lyracc. lakukan dengan cara yang serupa. dan bisa Anda temui pada buku-buku tentang administrasi server dan jaringan.flush().lyracc. Kita harus memanggil fungsi ini setiap kali kita menggunakan aliran output untuk mengirim data melalui jaringan.com\servertanggal\bin) kemudian ketik "java ServerTanggal".println() untuk mengirim data ke klien. Berikut ini adalah screen shot hasil pemanggilan program di atas pada dua konsol. Jika tidak. Metode ini digunakan untuk menjamin bahwa data yang telah dikirim pada aliran benar-benar dikirim ke tujuannya. akan tetapi tentunya pesan akan sangat lambat sampai di program klien. masingmasing untuk server dan kliennya. Lihat setelah memanggil keluar. yaitu buka konsol baru. dan diimpor ke dalam Eclipse dengan menggunakan instruksi pada halaman berikut. kemudian ketik "cd <nama_direktori_tempat_proyek_klien_berada>\bin" (di screen shot di atas direktornya berada di c:\belajarjava. klik kanan proyek tersebut dari dalam Eclipse -> Properties.com\klientanggal\bin) kemudian ketik "java KlienTanggal localhost".

Thread adalah unit terkecil dari eksekusi suatu program. Thread mengeksekusi rangkaian instruksi satu demi satu. Ketika sistem menjalankan program. dan seterusnya dan kemudian kembali ke thread pertama -. Thread disebut "mati" jika program selesai dieksekusi. akan tetapi perbedaanya tidank penting di sini). masing-masing prosesor atau core melakukan thread yang berbeda-beda). Akan tetapi sebenarnya komputer membagi waktu menjadi bagian-bagian kecil sehingga seolah-olah seluruh thread dijalankan secara bersama-sama. yang artinya beberapa hal bisa dilakukan bersama-sama.Pemrograman Serentak (Concurrency) Java adalah bahasa pemrograman banyak thread. Pada satu saat tertentu. dan hyperthreading. beberapa thread bisa tercipta dalam satu waktu. multicore. (Pada komputer dengan multiprosesor. kemudian thread lain. (Thread dalam konteks ini disebut proses. semua thread berjalan pada saat yang sama. Instruksi-instruksi dalam program akan dieksekusi oleh thread ini secara berantai. setelah itu beralih mengeksekusi thread yang lain. hanya ada satu thread yang bisa dijalankan. . Dalam sistem komputer modern. Pembagian waktu berarti CPU mengeksekusi suatu thread dalam kurun waktu tertentu. karena CPI hanya bisa melakukan satu hal dalam satu waktu. satu demi satu dari awal hingga akhir.kira-kira 100 kali per detik. komputer akan membuat thread baru. Di mata user.

Jika program harus menunggu seluruh input datang baru kemudian melakukan pengolahan. Artinya Java bisa membuat satu atau lebih thread yang bisa dijalankan secara paralel. thread akan mati secara otomatis. maka menggunakan banyak thread akan mempercepat eksekusi program. • • • • • • Dasar-dasar Thread Berbagi Sumber Daya Siklus Hidup Thread Kerjasama Antar Thread Kunci Mati (Deadlock) Menghentikan Thread Dasar-dasar Thread Cara termudah untuk membuat thread adalah membuat kelas turunan dari java. Metode paling penting adalah run(). masing-masing memiliki nomor identifikasi unik yang dibuat dengan menggunakan variabel statik. Thread juga digunakan untuk mempercepat suatu proses. yang bisa kita beban-lebihkan untuk melakukan tugas yang kita butuhkan.lang.threaddasar1. tentunya akan memakan waktu yang lebih lama. public ThreadDasar() { super("Thread ke-" + ++jumlahThread). menanggapi klik mouse. Penggunaan thread yang banyak digunakan adalah untuk membuat GUI (graphical user interface) yang responsif. dan sebagainya. Misalnya untuk melakukan video encoding dengan jumlah data besar. karena masing-masing thread dijalankan secara terpisah. dan pada saat yang sama mengolahnya sehingga proses pengolahan berjalan serentak. (Contoh-contoh pada bagian ini bisa diunduh untuk diimport ke dalam Eclipse. Lihat akhir halaman ini untuk tautannya) package com. start(). yang dibuat di dalam core bahasa. Hal ini adalah bagian mendasar. jika kita menggunakan seluruh core yang tersedia maka prosesnya akan dapat diselesaikan dengan cepat. Atau dengan kata lain run() adalah metode yang akan dijalankan bersamaan dengan thread lain. terutama apabila aliran network lambat atau pengolahannya memakan waktu lama. Setelah metode run() selesai dijalankan. Metode run() dibebanlebihkan untuk menghitung mundur hingga hitungMundur bernilai nol. public class ThreadDasar extends Thread { private int hitungMundur = 5. private static int jumlahThread = 0.lyracc. Pada dasarnya suatu program harus dapat terus bejalan dan pada saat yang sama tetap bisa menerima input dari user.Java adalah bahasa pemrograman banyak thread. bukan merupakan tambahan (add-on) seperti bahasa pemrograman lain. } . Jika kita memiliki CPU multiprocessor atau multicore. misalnya kita ingin membuat program yang menunggu suatu input I/O dari network. Contoh berikut membuat 5 thread.Thread. yang memiliki semua metode untuk membuat dan menjalankan thread. Tetap saja pemrogaman dengan banyak thread adalah sesuatu yang tidak mudah.

karena penjadwalan thread tidak dapat ditentukan dengan pasti (non-deterministik). Pada JDK lain kita akan melihat program akan mencetak 5 untuk seluruh thread hingga 1 untuk seluruh thread. program masih bisa berjalan seperti biasa. Metode start() pada kelas Thread digunakan untuk melakukan tugas tertentu sebelum metode run() dijalankan. Kita harus membuat suatu kondisi sehingga bisa keluar dari perulangan tersebut (misalnya pada contoh di atas. Pada objek biasa. i++) new ThreadDasar(). Akan tetapi pada thread. objek thread diberi nama melalui argumen pada konstruktornya. langkah-langkahnya adalah : konstruktor dipanggil untuk membuat objek.out. Pada metode main(). Nama ini dipanggil ketika metode run() melakukan penghitungan mundur. Karenanya. kita bisa memberi tahu penjadwal thread bahwa kita telah selesai dan memberi jalan kepada thread . 1 thread mungkin bisa melakukan tugasnya dengan cepat hingga selesai sebelum thread lain dijalankan. Keluaran dari program ini akan berbeda setiap kali dijalankan.println( getName() + " : " + hitungMundur ). Metode run() pada thread biasanya memiliki perulangan internal yang akan terus menerus dipanggil hingga tidak lagi digunakan. objek hanya bisa diambil oleh pemulung memori jika metode run() selesai dijalankan.public void run() { while (true) { System. Bahkan. kita lihat bahwa kita tidak menyimpan referensi ke objek tersebut. Pada contoh di atas. Program kita harus dibuat seaman mungkin. perulangan akan selesai jika hitungMundur bernilai 0). Jadi. } } /** * @param args */ public static void main(String[] args) { for(int i = 0. i < 5. dan kemudian metode run() dijalankan. kemudian memanggil start() untuk melakukan konfigurasi thread. karena setiap thread memiliki kesempatan yang sama untuk menjalankan program. tentunya objek ini akan langsung ditangkap oleh pemulung memori karena objek ini tidak direferensikan di manapun. dan objek Thread akan diberikan kepada pemulung memori setelah mencetak angka 1. kita bisa melihat perbedaan yang sangat jelas ketika kita menggunakan versi JDK yang berbeda. kita tidak boleh terpaku pada keluaran suatu kompiler. Yielding (menghasilkan) Jika kita tahu bahwa kita telah mendapatkan hasil yang kita inginkan pada metode run(). if (--hitungMundur == 0) return. Ketika objek Thread dibuat pada metode main(). yaitu dengan menggunakan metode getName(). Artinya pembagian waktunya lebih baik. untuk membuat suatu program multi-threading. thread dibuat beberapa kali kemudian dijalankan. JDK lama tidak melakukan pembagian waktu lebih cepat. artinya. run() dijalankan di dalam perulangan yang tak pernah berhenti (kita akan lihat nanti bagaimana menghentikan suatu thread dengan aman). Seringkali. } } Pada contoh program di atas. Jika kita tidak memanggil start() maka metode run() tidak akan pernah dijalankan. Misalnya.

lain untuk mendapatkan kesempatan pada CPU. kita bisa mengganti isi metode run() dengan public void run() { while (true) { System. try { sleep(100). atau mendesain agar suatu thread memanggil thread lain dengan suatu urutan tertentu.println( getName() + " : " + hitungMundur ). kita ubah metode run() menjadi seperti : public void run() { while (true) { System. Metode sleep() tidak digunakan untuk mengatur bagaimana thread akan berjalan menurut urutan tertentu. Tidur (sleeping) Cara lain untuk mengatur perilaku thread kita adalah dengan memanggil sleep untuk menunda eksekusi thread selama waktu tertentu (dalam mili detik). metode ini harus diletakkan di dalam blok try karena sleep() bisa melemparkan pengecualian. dan membiarkan metode yang memanggilnya menangkap pengecualian baru ini. } } Secara umum. kita lemparkan lagi pengecualian yang terjadi dengan pengecualian lain bertipe RuntimeException. oleh karena itu sifatnya disebut non-deterministik. Metode ini hanya menghentikan eksekusi suatu thread sementara. yaitu jika tidurnya diganggu sebelum waktunya selesai. Tetap saja urutannya tidak bisa ditentukan karena sifatnya yang non-deterministik. penjadwal . Prioritas Prioritas suatu thread digunakan untuk memberi tahu penjadwal thread tentang prioritas thread tersebut. Yang dijamin adalah bahwa thread akan tidur selama paling sedikit 100 mili detik (atau mungkin sedikit lebih lama hingga thread jalan kembali). if (--hitungMundur == 0) return. Pada contoh di atas. dan kita tidak bisa menggunakannya secara serius untuk memperbaiki kinerja aplikasi kita. yield().out. karena kita tidak tahu bagaimana pengecualian ini harus ditangani. yang artinya belum tentu dijalankan oleh penjadwal thread. if (--hitungMundur == 0) return.println( getName() + " : " + hitungMundur ). Misalnya pada kode berikut. } } } Ketika kita memanggil sleep().out. Hal ini terhadi misalnya apabila thread lain yang memiliki referensi ke thread ini memanggil interrupt() pada thread ini. Akan tetapi ini hanya sebagai petunjuk. cara terbaik mungkin tidak menggunakan thread sama sekali. yield mungkin berguna untuk situasi yang agak langka. Jika ada beberapa thread yang sedang diblok dan menunggu giliran untuk dijalankan. } catch (InterruptedException e) { throw new RuntimeException(e). Jika kita harus mengatur thread mana dahulu yang harus dijalankan. Tentunya cara terakhir lebih rumit dari yang dibayangkan. Misalnya pada contoh di atas. Urutan thread diatur oleh penjadwal thread yang memiliki mekanisme sendiri tergantung dari keadaan thread lain atau bahkan aplikasi lain di luar Java.

dan yang lain dengan prioritas minimum. dan MIN_PRIORITY pada kelas thread. Prioritas suatu thread bisa kita set kapan saja (tidak harus pada konstruktor) dengan metode setPriority(int prioritas) dan kita bisa membaca prioritas suatu thread dengan menggunakan metode getPriority(). Tanpa perhitungan ini. public class PrioritasThread extends Thread { private int hitungMundur = 5. Windows misalnya memiliki 7 tingkat dan Solaris memiliki 231 tingkat prioritas.E) / (double)i. start(). bagaimana thread pertama dijalankan lebih dulu sedangkan thread-thread lain berjalan seperti biasa dalam kondisi acak karena memiliki prioritas yang sama.prioritasthread.out. kita ubah konstruktornya untuk mengeset prioritas kemudian menjalankan thread. i++) new PrioritasThread(Thread.println(this.MIN_PRIORITY). // No optimization public PrioritasThread(int prioritas) { setPriority(prioritas). i++) d = d + (Math.PI + Math. Perhatikan contoh berikut : package com. for(int i = 0. } } Pada contoh di atas. Yang lebih pasti adalah menggunakan konstanta MAX_PRIORITY. Pada metode main() kita buat 6 thread.thread akan cenderung menjalankan thread dengan prioritas tertinggi terlebih dahulu.MAX_PRIORITY). tidak berarti thread dengan prioritas rendah tidak akan pernah dijalankan. Thread Daemon . akan tetapi sistem operasi memiliki tingkat prioritas yang berbeda-beda. i < 5. NORM_PRIORITY. i < 100000. Akan tetapi. System.000 kali. private volatile double d = 0.lyracc.toString() + " : " + hitungMundur). thread akan dilaksanakan sangat cepat dan kita tidak bisa melihat efek dari prioritas thread. Perhatikan keluarannya. yang pertama dengan prioritas maximum. Di dalam metode run() kita lakukan perhitungan matematika selama 100. if (--hitungMundur == 0) return. Meskipun JDK memiliki 10 tingkat prioritas. Tentunya ini perhitungan yang memakan waktu sehingga setiap thread harus menunggu giliran di saat thread lain sedang dijalankan. } } /** * @param args */ public static void main(String[] args) { new PrioritasThread(Thread. hanya lebih jarang dijalankan ketimbang thread dengan prioritas tinggi. } public void run() { while (true) { for(int i = 1.

} System. Menggabungkan thread Perintah join() bisa digunakan pada thread lain untuk menunda eksekusi hingga thread lain tersebut selesai dijalankan. // Harus dipanggil sebelum start start(). i++) new ThreadDaemon(). Hanya thread non-daemon saja yang bisa mencegah program untuk terus berjalan.lyracc. program tidak akan berhenti.join() pada thread t. public class ThreadDaemon extends Thread { public ThreadDaemon() { setDaemon(true). } public void run() { while (true) { try { sleep(100). Untuk mengetahui suatu thread adalah thread daemon atau bukan. } catch (InterruptedException e) { throw new RuntimeException(e). ataupun milidetik dan nanodetik). maka eksekusi thread a akan terhenti sementara hingga thread t selesai dijalankan (atau ketika t. kita bisa menggunakan perintah isDaemon(). akan tetapi thread ini bukan bagian penting dari suatu program. Suatu thread daemon akan membuat thread yang juga merupakan thread daemon. yaitu jika thread target tidak selesai dalam kurun waktu tersebut. program langsung berhenti sebelum thread bisa mencetak dirinya. jika thread a memanggil t. Artinya ketika semua thread yang bukan daemon selesai dijalankan. Ketika semua thread dimulai. } } Perintah setDaemon() sebelum metode start() dipanggil. Perhatikan contoh program berikut ini. Misalnya. program akan berhenti. package com. Ini karena semua thread kecuali main() adalah thread daemon.Thread daemon adalah thread yang bekerja di belakang layar yang memberikan layanan umum kepada thread-thread lain selama program berjalan. Pada metode run(). dan jika masih ada thread non-daemon yang masih dieksekusi. i < 5. } } /** * @param args */ public static void main(String[] args) { for (int i = 0.out.println(this).threaddaemon. . Kita bisa juga memanggil join() dengan argumen waktu (baik dalam mili detik.isAlive() bernilai false). thread diperintahkan untuk tidur selama 100 mili detik. eksekusi pada thread induk akan kembali dilakukan.

ThreadPemalas grr = new ThreadPemalas("grr". return.getName()).grr). } catch (InterruptedException e) { throw new RuntimeException(e).lyracc. 2000). } System. Mari kita lihat contoh berikut ini... sehingga klausa try . 2000). public ThreadPenggabung(String namaThread."). this. } catch (InterruptedException e) { System. " + "isInterrupted(): " + isInterrupted()). } System. ThreadPemalas pemalas) { super(namaThread).println(getName() + " sudah bangun. package com.Panggilan join() bisa dibatalkan dengan memanggil interrupt() pada thread induk. ThreadPenggabung anda = new ThreadPenggabung("anda". start(). catch diperlukan pada metode join(). } } class ThreadPenggabung extends Thread { private ThreadPemalas sleeper.brr). ThreadPenggabung saya = new ThreadPenggabung("saya".sleeper = pemalas.println(getName() + " selesai setelah " + sleeper. .join(). } } public class JoinDemo { /** * @param args */ public static void main(String[] args) { ThreadPemalas brr = new ThreadPemalas("brr".out. class ThreadPemalas extends Thread { private int waktu.println(getName() + " dibangunkan. int waktuTidur) { super(namaThread). waktu = waktuTidur.joindemo.out. } public void run() { try { sleeper. } public void run() { try { sleep(waktu). start(). public ThreadPemalas(String namaThread.out.

Di dalam klausa catch. Variasi Kode Pada contoh-contoh di atas. ThreadPenggabung adalah thread yang menunggu hingga ThreadPemalas selesai dengan tugasnya. Fungsi isInterrupted() melaporkan apakah thread ini diinterupsi atau tidak. i <= 5. } } public static void main(String[] args) { for (int i = 1.getName() + " : " + hitungMundur). i++) { // Buat thread baru dan jalankan .interrupt(). Oleh karenanya isInterrupted() akan selalu bernilai false pada program di atas. kelas kita mungkin saja merupakan kelas turunan dari kelas lain. Kita hanya membuat objek yang berfungsi sebagai thread dan tidak memiliki tugas dan fungsi lain. Tanda interupsi akan digunakan pada situasi lain yang mungkin berada di luar pengecualian. ThreadPenggabung yang tersambung juga akan menyelesaikan tugasnya. kita tidak bisa menurunkan kelas tersebut bersamaan dengan kelas Thread. interupsi akan dilaporkan. if (--hitungMundur == 0) return. setiap ThreadPemalas tersambung pada ThreadPenggabung. kita bisa menggunakan cara alternatif yaitu dengan mengimplementasi interface Runnable. semua objek thread yang kita buat diturunkan dari kelas Thread. public class RunnableSederhana implements Runnable { private int hitungMundur = 5. Akan tetapi ketika thread ini diinterupsi. baik karena dibangunkan melalui interupsi atau karena waktu sudah selesai.println(Thread. misalnya. jika ThreadPemalas selesai bekerja. maka tanda interupsi akan segera dihapus. Karena Java tidak mendukung pewarisan berganda.currentThread(). Akan tetapi. Dalam hal ini. yaitu dengan memanggil join() ke objek ThreadPemalas pada metode run()-nya.lyracc. kemudian pengecualiannya ditangkap oleh klausa catch. Pada metode utama main().grr. Contoh berikut mendemonstrasikan contoh penggunaannya : ThreadPemalas package com. yaitu metode run(). public void run() { while (true) { System. adalah thread yang akan ditidurkan sepanjang waktu yang diberikan pada konstruktornya. Metode run() bisa berhenti jika waktu tidur sudah habis atau ada interupsi yang terjadi. Runnable hanya memiliki satu metode untuk diimplementasi. Dan kita lihat pada keluarannya. } } Hasil keluarannya adalah seperti pada gambar berikut.out.runnablesederhana.

if (--hitungMundur == 0) return. } catch (InterruptedException e) { throw new RuntimeException(e).Thread a = new Thread(new RunnableSederhana(). sleep().out. Perhatikan beberapa variasi untuk mendeklarasikan dan menggunakan thread pada contoh berikut ini. start(). Kadang-kadang kita ingin juga membuat kelas dalam yang merupakan turunan dari kelas Thread. } } } Satu-satunya yang dibutuhkan oleh kelas RunnableSederhana adalah metode run(). kita harus secara eksplisit memberikan referensi dengan menggunakan Thread. // Kelas Dalam adalah kelas dalam (inner class) yang // merupakan kelas turunan kelas Thread private class Dalam extends Thread { Dalam(String nama) { super(nama). akan tetapi tidak berarti bahwa kelas ini bisa melakukan sesuatu seperti kelas Thread atau kelas-kelas turunan yang kita buat dari kelas ini. kelas dalam (inner class) juga bisa mengakses anggota kelas luar (outer class).start(). Akan tetapi. tanpa melalui objek lain.println(getName() + " : " + hitungMundur). Kita cukup menambahkan impement Runnable pada definisi kelasnya untuk membuat kelas yang bisa kita jadikan thread.lyracc. kemudian menjalankan start() sendiri. } } } } // akhir Dalam . package com. try { sleep(10). Kita harus membuat objek Thread sendiri seperti ditunjukkan dalam metode main() di atas. dan lainnya. akan tetapi jika kita ingin melakukan hal lainnya.currentThread(). seperti getName(). "Thread ke-" + i). private Dalam dalam. Ketika suatu kelas mengimplementasikan interface Runnable. Misalnya kita ingin membuat kelas baru yang merupakan kelas turunan dari suatu kelas lain. artinya kelas ini memiliki metode bernama run(). } public void run() { while (true) { System. // Kelas dalam bernama class KelasDalamBernama { private int hitungMundur = 5. a. kita masih bisa mengakses anggota kelas induk secara langsung. Dengan cara ini. Kemudahan yang ditawarkan oleh interface Runnable adalah kemungkinan untuk menggabungkannya dengan kelas dan interface lain.variasithread.

println(t. } } } }. if (--hitungMundur == 0) return.start().println(getName() + " : " + hitungMundur). } public void run() { while (true) { System.sleep(10).out. private Dalam dalam. nama).start(). } catch (InterruptedException e) { throw new RuntimeException(e). // Konstruktor KelasDalamAnonim public KelasDalamAnonim(String nama) { // Kelas anonim turunan Thread t = new Thread(nama) { public void run() { while (true) { System. if (--hitungMundur == 0) return. } } // akhir KelasDalamBernama // Kelas dalam anonim class KelasDalamAnonim { private int hitungMundur = 5. private Thread t.getName() + " : " + hitungMundur). try { sleep(10). } } // akhir KelasDalamAnonim // Kelas dalam implementasi runnable bernama class KelasRunnableBernama { private int hitungMundur = 5. t. . try { Thread.// Konstruktor KelasDalamBernama // Membuat objek baru yang merupakan instansi kelas Dalam public KelasDalamBernama(String nama) { dalam = new Dalam(nama). Dalam(String nama) { t = new Thread(this.out. // Kelas Dalam adalah kelas dalam (inner class) yang // merupakan kelas yang mengimplementasi Runnable private class Dalam implements Runnable { Thread t. // akhir kelas anonim t. } catch (InterruptedException e) { throw new RuntimeException(e).

try { Thread. if (--hitungMundur == 0) return. } } // akhir KelasRunnableAnonim // Menjalankan thread dari dalam metode dan kelas anonim class ThreadViaMetode { private int hitungMundur = 5.currentThread(). private Thread t.out. private Thread t.} } } } // akhir kelas Dalam // Konstruktor KelasRunnableBernama // Membuat objek baru yang merupakan instansi kelas Dalam public KelasRunnableBernama(String nama) { dalam = new Dalam(nama).out.println(Thread. } } } }. } } // akhir KelasRunnableBernama // Kelas dalam implementasi runnable anonim class KelasRunnableAnonim { private int hitungMundur = 5.nama = nama. public ThreadViaMetode(String nama) { this. public KelasRunnableAnonim(String nama) { t = new Thread(new Runnable() { public void run() { while (true) { System. } catch (InterruptedException e) { throw new RuntimeException(e). // akhir kelas dalam anonim t. . nama).getName() + " : " + hitungMundur).println(getName() + " : " + hitungMundur). if (--hitungMundur == 0) return.start().sleep(10). private String nama. } public void runThread() { if (t == null) { // Definisi kelas anonim dari dalam metode t = new Thread(nama) { public void run() { while (true) { System.

Kelas ketiga dan keempat pada contoh di atas mirip dengan contoh pertama dan kedua. kita tidak perlu membuat seluruh kelas menjadi Runnable jika hanya kita ingin memulai proses di bagian tertentu program kita. Jika metode kelas lain membutuhkan akses ke t. yaitu proses. Akan tetapi. mungkin cara ini lebih cocok daripada mengimplementasikan kelas khusus untuk melakukan fungsi-fungsi thread. KelasDalamAnonim adalah alternatif dari KelasDalamBernama di mana kelas dalamnya merupakan kelas anonim yang merupakan kelas turunan dari kelas Thread. KelasDalamBernama[. Artinya juga. seringkali kita membuat thread hanya untuk memanfaatkan [code]Thread saja.} } } } }. Kita bisa memanggil metode tersebut jika kita siap untuk menjalankan thread ini. Metode ini akan selesai setelah thread berjalan. mungkin lebih masuk akal untuk menyembunyikan thread di dalam kelas kita menggunakan kelas dalam. . new KelasRunnableAnonim("KelasRunnableAnonim"). akan tetapi menggunakan interface Runnable. maka kita bisa menggunakannya seperti Thread biasa tanpa perlu mengetahui tipe objek t sesungguhnya. tetntunya kita akan terbebas dari cara pandang berorientasi objek yaitu "semuanya adalah objek". Jika kita menganggap suatu thread sebagai proses. Cara ini baik jika kita ingin kelas dalam tersebut memiliki suatu kemampuan tertentu (metode lain) yang ingin kita gunakan. } } Jika kita menggunakan Runnable. pada dasarnya kita menyatakan bahwa kita ingin membuat suatu proses -. Jika thread hanya melakukan tugas sampingan. Kelas ThreadViaMetode menunjukkan bagaimana membuat thread dari dalam metode. Karenanya.code] membuat kelas dalam yang merupakan kelas turunan dari kelas Thread. } catch (InterruptedException e) { throw new RuntimeException(e). new ThreadViaMetode("ThreadViaMetode"). Kelas anonim ini dibuat di dalam konstruktor dan disimpan dalam bentuk referensi t bertipe Thread. new KelasDalamAnonim("KelasDalamAnonim"). artinya kita mungkin tidak perlu membuat kelas yang memiliki nama. Contoh ini hanya ingin menunjukkan bahwa menggunakan Runnable tidak menambah nilai apa-apa. apakah kita ingin menganggap suatu thread sebagai objek atau sesuatu yang sama sekali berbeda. Tentunya hal ini tergantung dari cara pandang kita.yang implementasinya berada di dalam metode run() -.runThread().bukan suatu objek yang melakukan proses tertentu. // akhir kelas dalam anonim t. new KelasRunnableBernama("KelasRunnableBernama").start(). kecuali membuat kodenya lebih sulit dibaca. try { sleep(10). dan membuat instansi kelas ini di dalam konstruktornya. } } // akhir ThreadViaMetode public class VariasiThread { public static void main(String[] args) { new KelasDalamBernama("KelasDalamBernama").

Akan tetapi. membaca. tampilan. input/output dan lain-lain. Berikut ini adalah program versi pertama. hard disk. public void berikut() { i++. Kita harus bisa memahami bagaimana thread-thread bekerja sama dalam berbagi sumber daya pada komputer. menghapus data yang sama. } public int ambilNilai() { . kita akan melihat ada beberapa kejutan yang terjadi. tentunya hal ini menjadi lebih rumit. menampilkan gambar di layar yang sama. terutama karena suatu thread bersifat non-deterministik. di mana suatu kelas "menjamin" bahwa ia akan memberikan angka genap setiap kali kita memanggil ambilNilai(). karena perpindahan data dari satu tempat ke tempat lain diatur hanya oleh satu alur.Berbagi Sumber Daya Kita bisa bayangkan sebuah program dengan thread tunggal hanya memiliki satu hal yang berpindah dari satu bagian ke bagian lain secara harmonis. menulis. melakukan debit di rekening yang sama. menghapus data yang sama. Jika ada dua atau lebih thread yang menggunakan. Sepertinya ini cara yang tidak perlu. Ini bukan hal yang mudah. Akan tetapi. package com. i++. mencetak di printer yang sama. Kita tidak bisa menentukan atau memprediksi kapan suatu thread akan dijalankan oleh penjadwal. Bisa saja pada saat yang bersamaan dua thread mencoba untuk mengakses data yang sama. Tabrakan sumber daya harus bisa dicegah sedini mungkin.selalugenap. ada thread kedua yang dinamakan Hansip yang selalu memanggil ambilNilai() untuk mengecek apakah nilainya selalu genap.lyracc. hasilnya pasti selalu genap. karena setelah kita melihat kode berikut. sehingga program yang kita buat menjadi lebih baik. Cara Buruk Mengakses Sumber Daya Kita ambil contoh berikut. termasuk memori. public class SelaluGenap { private int i.

ambilNilai(). while (true) genap.sifatnya harus final karena objek ini harus bisa diakses oleh kelas anonim yang berupa Thread. // Jika ganjil.exit(0). maka bilangan tersebut akan dicetak di layar kemudian keluar dari program.start(). } public static void main(String[] args) { final SelaluGenap genap = new SelaluGenap(). objek SelaluGenap akan dibuat -. Jika nilai yang dibaca oleh thread berupa bilangan ganjil. new Thread("Hansip") { public void run() { while (true) { int nilai = genap.berikut().out. .println(nilai). } } } }. } } Pada metode main(). keluar dan cetak nilainya if (nilai % 2 != 0) { System.return i. System.

Ketika suatu thread berusaha untuk mengeksekusi suatu perintah yang diberi kata kunci synchronized. Akan tetapi supaya program banyak thread bisa bekerja dengan baik. maka mereka bisa masuk dan mengunci pintunya. Thread lain yang mau menggunakan kamar mandi "diblok" sehingga tidak bisa masuk. Kunci ini sering disebut mutex atau mutual exclusion. hampir semua metode serentak melakukan akses serial ke suatu sumber daya yang digunakan bersama. terutama di saat-saat kritis. Java memiliki fitur untuk mencegah terjadinya tabrakan sumber daya. Artinya hanya satu thread yang bisa mengakses suatu sumber daya pada suatu waktu. dan mereka ingin masuk sendirian. Biasanya hal ini dilakukan dengan membuat kunci sehingga satu thread saja yang bisa mengakses kunci tersebut. Karena tidak ada "antrian" maka kita tidak tahu siapa yang harus masuk berikutnya. Beberapa orang (thread) ingin masuk ke kamar mandi (sumber daya bersama). Jika ya. Thread kedua bisa jalan ketika thread pertama baru selesai menjalankan i++. seseorang harus mengetok pintu untuk mengetahui apakah ada orang di dalamnya. sehingga thread harus menunggu hingga seseorang keluar dari kamar mandi. Mencegah tabrakan seperti ini bisa dicegah dengan meletakkan kunci pada sumber daya ketika sedang digunakan. padahal proses belum selesai. Di sini thread kedua menganggap ada kesalahan perhitungan. Kita tidak pernah tahu kapan suatu thread akan jalan. jika banyak orang menunggu di depan kamar mandi. Analogi di atas sedikit berbeda jika ketika seseorang keluar dari kamar mandi dan ada beberapa orang yang ingin mengakses kamar mandi secara bersamaan. Java akan mengecek apakah sumber daya tersebut tersedia. Mari kita ambil contoh di rumah kita hanya ada satu kamar mandi.Apa yang terjadi adalah program pasti akan keluar dengan mencetak nilai ganjil. kita bisa memberi tahu penjadwal thread dengan perintah yield dan setPriority() akan tetapi tetap saja masih sangat bergantung kepada JVM dan implementasi pada suatu platform dan tidak bisa ditentukan dengan pasti siapa yang berhak masuk terlebih dahulu. maka kunci ke sumber daya tersebut akan diambil. variabel i) sedang diakses apakah sedang digunakan atau tidak. Untuk masuk ke dalam kamar mandi. yang pertama di dalam metode berikut(). Thread pertama yang sedang mengubah variabel i seharusnya mengunci variabel ini sehingga thread kedua yang ingin mengambil nilainya harus menunggu hingga proses penambahan selesai. yaitu dengan menggunakan kata kunci synchronized. Seperti telah diulas sebelumnya. artinya penjadwal thread bersifat non-deterministik. Ini berarti ada ketidakstabilan dalam program tersebut. Jika tidak ada. Ini adalah contoh masalah mendasar dengan pemrograman banyak thread. Yang terjadi adalah. Kadang-kadang kita memang tidak peduli ketika suatu sumber daya (dalam contoh di atas. kemudian . Pemecahan Masalah Tabrakan Sumber Daya Bersama Untuk memecahkan masalah tabrakan pada thread. maka siapa yang paling dekat dengan kamar mandi akan masuk terlebih dahulu. kita harus mencegah supaya dua thread tidak mengakses sumber daya yang sama.

Metode ini akan berjalan terus menerus. Ada juga kunci per kelas. thread lain diblok untuk mengeksekusi metode synchronized lain dalam kelas itu hingga thread pertama selesai. Memperbaiki SelaluGenap Kita akan ubah sedikit program SelaluGenap di awal bagian ini untuk memberikan kata kunci synchronized pada metode berikut() dan ambilNilai(). Untuk mengontrol akses ke sumber daya bersama. Karena hanya ada satu kunci untuk setiap objek. kemudian secara periodik mengecek waktu saat . Akan tetapi synchronized tidak selalu berhasil. yang artinya kunci ini berlaku untuk suatu kelas. synchronized void a() { /* perintah Anda di sini */ } synchronized void b() { /* perintah Anda di sini */ } Setiap objek memiliki kunci masing-masing yang otomatis dibuat ketka objek tersebut dibuat (kita tidak perlu membuat kode spesial). Satu thread bisa mengunci objek beberapa kali. I/O atau bahkan printer. di mana kita harus memberi kunci di setiap akses ke sumber daya bersama. Artinya jika thread sedang mengeksekusi salah satu metode synchronized. atau bisa juga berupa file. Setiap kali suatu metode selesai. kita biasanya membungkusnya dalam bentuk objek. yang artinya thread lain bisa mulai menggunakan metode pada objek ini.perintah dijalankan. kunci akan dilepas. Ketika objek tidak terkunci lagi. Karena biasanya data dari suatu kelas kita buat private dan akses ke memori hanya bisa dilakukan dengan menggunakan metode. oleh karena itu kita akan gunakan waktuMulai untuk menyimpan waktu ketika thread mulai berjalan. maka kita tidak mungkin menyimpan 2 data pada satu tempat pada saat yang bersamaan. Sumber daya bersama bisa berbentuk lokasi memori (dalam bentuk objek). Ini terjadi jika satu metode memanggil metode lain di kelas yang sama. Di sini lah kunci pemrograman serentak. dan setelah selesai melepaskannya kembali. JVM akan melacak berapa kali objek tersebut terkunci. Metode lain yang mencoba untuk mengakses sumber daya tersebut bisa diberi kata kunci synchronized. maka metode yang tidak diberi kunci akan tetap bebas untuk dieksekusi mengabaikan ada atau tidaknya kunci. kemudian metode tersebut memanggil metode lain lagi di kelas yang sama dan seterusnya. maka kita bisa mencegah tabrakan dengan membuat metode menjadi synchronized. objek tersebut dikunci dan tidak boleh ada lagi metode synchronized yang bisa dieksekusi hingga metode sebelumnya selesai dijalankan dan kunci dilepas. maka kuncinya bernilai 0. Ketika kita memanggil metode yang diberi tanda synchronized. Otomatis semua objek yang diciptakan dari kelas yang sama memiliki kunci bersama. Caranya yaitu dengan menggunakan synchronized static metode sehingga suatu objek bisa juga mengunci kelas sehingga objek lain yang menggunakan metode ini tidak bisa jalan apabila sedang digunakan oleh objek lain. Berikut ini adalah contoh pendeklarasian synchronized. Jika kita hanya meletakkan kunci pada salah satu metode.

public void run() { while (true) { int nilai = genap. package com. new Thread("Hansip") { // mencatat waktu ketika thread dimulai private long waktuMulai = System.ini. kita hentikan proses kemudian mencetak hasilnya. i++. keluar dan cetak nilainya if (nilai % 2 != 0) { . synchronized public void berikut() { i++. public class SelaluGenapSynchronized { private int i.ambilNilai(). // Jika ganjil. } public static void main(String[] args) { final SelaluGenapSynchronized genap = new SelaluGenapSynchronized(). } synchronized public int ambilNilai() { return i. Jika proses sudah berjalan lebih dari 4 detik.currentTimeMillis().lyracc.selalugenapsynchronized.

kata kunci ini digunakan dengan menyatakan objek mana yang memiliki kunci yang harus dicek sebelum bagian ini dijalankan. } } } }.println(nilai). Berikut ini adalah bentuk umum dari pernyataan synchronized untuk melindung bagian kritis : synchronized(objekKunci) { // Kode di bagian ini hanya bisa diakses // Jika objekKunci sedang tidak diakses oleh thread lain } .System.exit(0). while (true) genap.currentTimeMillis() . } // Selesaikan program jika sudah melewati 4 detik if (System. } } Bagian Kritis Kadang-kadang kita hanya ingin mencegah beberapa thread untuk mengakses sebagian kode saja di dalam suatu metode. Bagian kode yang kita ingin lindungi ini disebut bagian kritis (critical section) dan juga bisa dibuat dengan kata kunci synchronized. bukan keseluruhan metode.start().out.println(nilai). System.out. System.berikut(). Akan tetapi.exit(0).waktuMulai > 4000) { System.

sehingga belum bisa berbuat apa-apa. 2. Salah satunya adalah jika thread menunggu di bagian kritis sementara ada thread lain yang sedang menjalankan bagian kritis tersebut. Kuncinya adalah komunikias antar thread yang diimplementasi dengan aman dalam metode-metode pada kelas Object. Diblok : Thread seharusnya bisa berjalan. . sebelum blok ini bisa dieksekusi. meneruskan eksekusi. kita bisa memanggi metode stop(). langkah berikutnya adalah belajar bagaimana membuat thread dapat bekerja sama satu sama lain. hingga keluar dari bagian kritis. Sebelumnya. Bisa-jalan : Artinya objek ini sudah dimulai dan sudah bisa dijalankan oleh mekanisme pembagian waktu oleh CPU. selama diperintahkan oleh penjadwal thread. akan tetapi program bisa berada dalam kondisi tidak stabil jika metode ini dipanggil. wait() dan notify() Pertama-tama penting untuk mengerti bahwa sleep() tidak melepas kunci thread ketika dipanggil. Baru : Objek thread baru saja dibuat. Kerjasama Antar Thread Setelah kita mengerti bagaimana thread bisa bertabrakan satu sama lain. Artinya jika sleep() dipanggil dari dalam bagian kritis. akan tetapi thread lain sedang memegang kuncinya. • Thread sedang menunggu selesainya operasi I/O • Thread mencoba memanggil metode dengan kata kunci synchronized. Sehingga thread ini bisa jalan kapan saja. Siklus Hidup Thread Suatu thread bisa berada dalam salah satu kondisi berikut : 1. akan tetapi belum mulai dijalankan. Kita akan lihat beberapa metode lain untuk menghentikan thread di bagian berikutnya. Bagaimana Suatu Thread Berada dalam Kondisi Diblok Ketika suatu thread diblok. sehingga thread lain bisa masuk ke dalam bagian kritis. Sedangkan wait() melepas kunci ketika dipanggil. kunci pada objek objekKunci harus dicek terlebih dahulu. yaitu wait() dan notify(). Mati : suatu thread biasanya mati ketika selesai menjalankan metode run(). 3. Suatu thread dapat diblok karena beberapa alasan sebagai berikut : • Kita memberi perintah thread untuk tidur dengan sleep(milidetik) sehingga thread tidak akan jalan dalam waktu yang sudah disebutkan • Kita memerintahkan thread untuk menunggu dengan perintah wait(). Ketika suatu thread berada dalam kondisi diblok. maka bagian kritis tidak bisa dimasuki hingga thread lain selesai dan melepas kuncinya. akan tetapi ada yang menghalanginya. Jika thread lain telah mengunci ojek ini.Bentuk umum di atas juga disebut blok tersinkron (synchronized block). penjadwal thread akan mengabaikannya dan tidak memberikan waktu CPU. dan bagaimana caranya mencegah tabrakan antar thread. 4. ada suatu alasan kenapa thread tersebut tidak bisa terus berjalan. maka thread lain tidak bisa masuk hingga thread yang memanggil sleep() bangun. Thread tidak akan dijalankan kembali hingga diberikan pesan notify() atau notifyAll().

notify().lyracc. wait() digunakan jika kita menunggu sesuatu yang dikontrol oleh sesuatu di luar kontrol metode kita (di mana sesuatu ini hanya bisa diubah oleh thread lain). atau hingga waktu tunggu berlalu. anggap suatu restoran memiliki satu orang koki dan satu orang pelayan. dan hanya ketika notify() dipanggil. Pelayan harus menunggu hingga si koki selesai memasak makanan. Yang pertama memiliki argumen waktu dalam bentuk mili detik (mirip dengan sleep(). Ketika koki selesai. notify() dan notifyAll() adalah dari dalam blok atau metode synchronized. Misalnya. } Biasanya. Kita juga bisa meminta suatu objek untuk memanipulasi kuncinya sendiri. Pesan ini berarti bahwa thread yang memanggil wait(). Sebagai contoh. pertamatama kita harus mengambil kuncinya. notify() atau notifyAll() dari luar metode atau blok synchronized.rumahmakan. Kita bisa menggunakan wait() untuk memerintahkan suatu thread untuk menunggu hingga sesuatu tersebut berubah. Aspek penting dari wait(). kemudian menunggu kembali. Caranya. tidak peduli apakah kelas tersebut merupakan kelas turunan dari Thread atau bukan. karena cara ini akan memboroskan penggunaan CPU. hal ini sangat penting karena semua objek memiliki kunci. Jika kita memanggil wait(). Kita tidak ingin menunggu dan berulang-ulang menguji apakah sesuatu itu sudah tersedia. Jenis wait() ini akan terus berlangsung hingga dibatalkan dengan notify atau notifyAll(). kemudian membawa makanan ini ke customer. Meskipun kelihatan janggal. jika kita ingin memanggil notify() ke suatu objek x. Bentuk kedua dari wait() adalah wait() yang tidak memiliki argumen. ia akan memberi tahu pelayan. Perbedaannya dengan sleep() adalah : • wait() melepaskan kunci • Kita bisa membatalkan wait() dengan menggunakan notify() atau notifyAll(). maka thread tersebut akan bangun dan mengeceknya. kita akan mendapatkan pengecualian IllegalMonitorStateException dengan pesan kesalahan yang tidak dimengerti. class Pesanan { private int i = 0. notify() atau notifyAll() harus memiliki kunci objek sebelum bisa memanggil salah satu metode ini. seprti "thread ini bukan pemiliknya". notify() dan notifyAll() adalah metode ini merupakan bagian dari kelas dasar Obejct dan bukan bagian dari kelas Thread seperti sleep(). Sebetulnya satu-satunya tempat kita bisa memanggil wait(). dan pelayan disebut sebagai konsumen. (sleep() bisa dipanggil dari manapun karena ia tidak berhubungan dengan kunci suatu objek). seperti : synchronized(x) { x. kita harus melakukannya di dalam blok synchronized untuk mengambil kunci x. } . Artinya kita bisa memanggil wait() dari dalam metode synchronized. package com. Dengan kata lain wait() digunakan melakukan aktifitas tak-sinkron antara beberapa thread.i = i. Koki di sini kita sebut sebagai produsen. akan tetapi ketika program dijalankan. compiler tidak akan memperingatkan Anda. public Pesanan(int i) { this.Ada dua bentuk wait().

out. } } System. i < 10.public String toString() { return "pesanan " + i.out.print("Pesanan selesai! ").notify().pesanan). // coba panggil pelayan jika tidak sibuk synchronized (pelayan) { pelayan. pelayan = p. public Koki(RumahMakan r. . public Pelayan(RumahMakan r) { rumahMakan = r.pesanan == null) { rumahMakan.pesanan == null) // tunggu hingga dipanggil dengan notify oleh Koki synchronized (this) { try { wait(). Pelayan p) { rumahMakan = r. pesanan sekarang kosong rumahMakan.pesanan = null. } public void run() { // masak 10 makanan for (int i = 0.pesanan = new Pesanan(i). start(). } } } // akhir kelas Pelayan class Koki extends Thread { private RumahMakan rumahMakan. System.println("Pelayan mengantarkan " + rumahMakan. // pesanan sudah diantar. } } // akhir kelas Pesanan class Pelayan extends Thread { private RumahMakan rumahMakan. } catch (InterruptedException e) { throw new RuntimeException(e). } public void run() { while (true) { while (rumahMakan. i++) { if (rumahMakan. } } try { sleep(100). private Pelayan pelayan. start(). } catch (InterruptedException e) { throw new RuntimeException(e).

Pelayan pelayan = new Pelayan(rumahMakan). Dengan melakukan ini. Pada aplikasi yang lebih kompleks.} } System. Pada metode run(). public static void main(String[] args) { RumahMakan rumahMakan = new RumahMakan(). Karena panggilan notify() dilakukan di dalam klausa synchronized. Mungkin ini agak terasa ganjil karena ketika thread ini dibangunkan ketika menunggu pesanan. System. karena ia harus ke sana untuk mengantarkan pesanan dari "jendela pemesanan". new Koki(rumahMakan. yaitu rumahMakan.png" alt="" /> adalah kelas sederhana yang berisi pesanan.println(). . misalnya jika pelayannya banyak. Pesanan yang dia masak akan dia letakkan pada jendela pesanan (dalam hal ini rumahMakan.pesanan. maka thread akan kembali tidur. maka sudah bisa dipastikan Koki memanggil pelayan jika pelayan tersebut sedang tidak digunakan oleh thread lain. } } Keluarannya ada sebagai berikut. Kunci ini yang akan digunakan oleh Koki untuk membangunkan Pelayan jika makanan sudah siap dengan metode notify(). Pada contoh sederhana di atas. thread lain mungkin sudah keburu mengantarkan pesanannya ketika thread ini sedang bangun.lyracc. kita menjamin bahwa kondisi di atas akan terpenuhi sebelum thread mendapatkan sesuatu yang ditunggu. Jika thread sudah dibangunkan akan tetapi pesanan tidak ada. Konstruktor menerima angka yang diibaratkan seperti pesanan.. Kuncinya dimiliki oleh pelayan ini sendiri. Koki membuat objek Pesanan. Setiap pelayan nanti akan menguji apakah panggilan itu untuknya atau tidak. seharusnya pesanannya sudah tersedia khan? Masalahnya jika aplikasinya terdiri dari banyak pelayan. kita bisa memanggil notifyAll() untuk membangunkan semua pelayan. Pelayan masuk dalam mode menunggu. Perhatikan bahwa wait() ditulis di dalam pernyataan while untuk menguji apakah pesanan sudah datang.out. kemudian setelah selesai akan memanggil Pelayan dengan notify().exit(0).pesanan) dan dia juga harus tahu siapa Pelayan yang akan mengantarkan pesanan yang sudah selesai dimasak.println("Makanan habis. Untuk itu. <img src="/sites/java. } } // akhir kelas Koki public class RumahMakan { Pesanan pesanan.out. Seorang Pelayan harus tahu RumahMakan tempat ia bekerja. lebih aman apabila kita menggunakan bentuk berikut untuk semua aplikasi yang menggunakan wait() : Pesanan while (sesuatuYangDitunggu) wait(). kemudian membebanlebihkan metode toString() untuk mencetak objek ini langsung dengan System.").com/files/kerjasamathread_gbr1. Objek Koki harus tahu di rumah makan mana ia bekerja. pelayan).

yang suatu saat nanti terjadi ketika program sudah dirilis (bahkan sering kali deadlock ini juga tidak bisa direproduksi sehingga menyulitkan debugging).*. Kesulitannya adalah karena ilmuwan tidak punya uang. dia harus mengambil garpu di sebelah kiri dan kanannya. public String toString() { return "garpu " + nomor. kita akan segera tahu dan memperbaikinya. Jika kita menggunakan banyak ilmuwan dan waktu berfikir yang lama. akan tetapi ketika mereka makan. Mereka membutuhkan dua garpu untuk mengambil spaghetti dari mangkok di tengah meja. Hanya ada 5 garpu yang tersedia. Kita bisa mengganti beberapa konstanta sehingga deadlock bisa lebih cepat terjadi. dan seterusnya.lyracc. class Garpu { private static int hitung = 0. mereka tidak membutuhkan apa-apa. akan tetapi mungkin menyimpan bahaya laten deadlock. Misalnya ada 5 orang ilmuwan (kita bisa mengganti berapa saja). Mencegah deadlock dengan membuat desain program yang lebih hati-hati sangat penting ketika kita membuat program banyak thread. Ketika ilmuwan ingin makan.ilmuwanmakan. mereka tidak mampu untuk membeli banyak garpu. yaitu "ilmuwan yang sedang makan".util. Persoalan ini menjadi menarik karena menjelaskan bahwa program yang sepertinya berjalan dengan benar akan tetapi mudah terkena deadlock. private int nomor = hitung++. Mari kita lihat contoh klasik dari deadlock yang ditemukan oleh Dijkstra. atau bisa dicegah sama sekali. Kasus ini dinamakan kunci mati (deadlock). Sering kali program yang kita buat tampak baik-baik saja. mereka duduk di meja dengan jumlah alat makan yang terbatas. . Garpu-garpu ini diletakkan di meja tersebar di dekat masing-masing ilmuwan ini. private static int hitung = 0. Ketika mereka berfikir. Karenanya mungkin saja satu thread tersangkut menunggu suatu thread. Jika program yang kita buat tiba-tiba mengalamai deadlock. Parameter-parameter yang bisa diganti adalah konstanta bertipe final static int di awal deklarasi kelas IlmuwanMakan.Kunci Mati (Deadlock) Thread bisa diblok dan objek bisa memanggil metode synchronized ke suatu objek sehingga objek lain tidak bisa mengakses objek tersebut hingga kuncinya dilepas. Ilmuwanilmuwan ini menghabiskan sebagian waktu untuk berfikir dan sebagian lagi untuk makan. Jika rangkaian kunci kembali ke thread pertama. Akan tetapi permasalahan utamanya adalah deadlock sulit untuk dideteksi. maka ia harus menunggu hingga garpunya selesai digunakan. deadlock akan lebih jarang terjadi. Jika ilmuwan di sebelahnya sedang menggunakan garpu tersebut. private int nomor = hitung++. } } // akhir kelas Garpu class Ilmuwan extends Thread { private static Random acak = new Random(). maka semua thread akan diam menunggu satu sama lain dan tidak akan pernah jalan. package com. import java. akan tetapi thread yang ditunggu ini juga sedang menunggu thread lain.

out.private Garpu garpuKiri. // kemudian cek apakah garpu kanannya tersedia synchronized (garpuKanan) { System.println(this + " berfikir"). private Garpu garpuKanan. } // Ilmuwan berfikir. static int waktuFikirMaks = IlmuwanMakan.println(this + " punya " + this. } // Metode ketika thread dijalankan // masing-masing ilmuwan akan berfikir kemudian makan // begitu seterusnya public void run() { while (true) { berfikir(). Garpu kanan) { garpuKiri = kiri.println(this + " makan").nextInt(waktuFikirMaks)). public Ilmuwan(Garpu kiri.println(pesan). try { sleep(acak.garpuKiri + ".out. garpuKanan = kanan.garpuKanan). Menunggu " + this. final String pesan) { super(true). // Daemon thread schedule(new TimerTask() { public void run() { System.out. gunakan sleep untuk mensimulasi public void berfikir() { System. makan(). } } // Ilmuwan makan public void makan() { // cek apakah garpu kirinya tersedia synchronized (garpuKiri) { System.out. .WAKTU_FIKIR_MAKS. start(). } } } public String toString() { return "Ilmuwan " + nomor. } } } // akhir kelas ilmuwan // Kelas timeout untuk menghentikan proses setelah // waktu yang ditentukan class Timeout extends Timer { public Timeout(int jeda. } catch (InterruptedException e) { throw new RuntimeException(e).

"). // Garpu pertama hanya sebagai penanda // yaitu garpu di kiri ilmuwan pertama Garpu pertama = kiri.garpu kirinya adalah garpu kanan ilmuwan sebelumnya . // mili detik. // mili detik atau buat 0 jika tidak ingin timeout public static void main(String[] args) { // Buat array ilmuwan sejumlah JUMLAH_ILMUWAN Ilmuwan[] ilmuwan = new Ilmuwan[JUMLAH_ILMUWAN]. } // // // // // // // // if Sekarang buat ilmuwan terakhir Jika kita ingin membuat deadlock (makan menghadap meja) : .garpu kanannya adalah garpu kiri ilmuwan pertama Jika tidak (makan berbalik arah) . . Garpu kanan = new Garpu(). jeda). // Mula-mula buat 2 garpu Garpu kiri = new Garpu().1) { ilmuwan[i++] = new Ilmuwan(kiri. kiri). pertama). else ilmuwan[i] = new Ilmuwan(pertama.garpu kanannya adalah garpu kanan ilmuwan sebelumnya (DEADLOCK) ilmuwan[i] = new Ilmuwan(kiri.length .exit(0).} } // akhir kelas Timeout System. // bisa diganti final static int WAKTU_FIKIR_MAKS = 10. int i = 0. kiri = kanan. "Waktu habis. kanan = new Garpu(). // Kelas utama public class IlmuwanMakan { final static int JUMLAH_ILMUWAN = 3. // buat masing-masing ilmuwan // yang pertama memiliki garpu kiri dan kanan // ilmuwan kedua duduk di sebelah kanan ilmuwan pertama // sehingga garpu kirinya adalah garpu kanan ilmuwan pertama // buat garpu baru untuk garpu kanannya // demikian seterusnya hingga JUMLAH_ILMUWAN minus 1 while (i < ilmuwan. } }. // Keluar dari program setelah jeda waktu selesai if (WAKTU_TIMEOUT > 0) new Timeout(WAKTU_TIMEOUT.garpu kirinya adalah garpu kiri ilmuwan pertama . // ubah ini menjadi false untuk mencegah deadlock final static int WAKTU_TIMEOUT = 10000.. kanan). bisa diganti final static boolean DEADLOCK = true.

Jika garpu sedang digunakan oleh ilmuwan lain. Sedangkan garpu kanan ilmuwan baru adalah objek garpu baru. akan tetapi garpu kanannya adalah garpu pertama. garpu kiri ilmuwan terakhir adalah garpu kanan ilmuwan sebelumnya. atau waktu fikir ilmuwan sangat panjang). Untuk menghindari deadlock. Padahal sebenarnya tidak demikian. Variabel keempat. Bayangkan meja ilmuwan dibuat dalam urutan melingkar berlawanan arah jarum jam. Mungkin kita beranggapan dengan mengubah waktu berfikir setiap ilmuwan. Setelah digunakan. . Ada empat konstanta yang bisa kita ubah-ubah di dalam kelas IlmuwanMakan. Garpu-garpu ini akan diambil oleh ilmuwan ketika hendak makan. maka nilai variabel ini akan digunakan sebagai argumen perintah sleep() dalam kelas Ilmuwan. Garpu kiri ilmuwan baru adalah garpu kanan ilmuwan sebelumnya. Jika nilainya tidak nol. garpu kiri dipindah ke garpu kanan. atau jumlah ilmuwan banyak. Pada versi di mana DEADLOCK bernilai true. Dalam metode run() serorang ilmuwan makan dan berfikir terus menerus. Setelah array objek Ilmuwan dibuat. Pada proses yang sulit atau tidak mungkin deadlock (jika variabel DEADLOCK false. seringkali sebelum deadlock terjadi. Jika bernilai true maka program cepat atua lambat pasti akan mengalami deadlock. Dengan pengaturan seperti ini.} } Kelas Garpu dan Ilmuwan menggunakan penghitung otomatis untuk memberi nomor identifikasi tersendiri untuk setiap objek Garpu dan Ilmuwan yang diciptakan. Deadlock ditandai dengan semua ilmuwan saling menunggu satu sama lain hingga waktu time out berakhir. maka proses akan berhenti pada waktu time out. kita bisa menggantinya dengan false. Coba ganti variabelnya dengan beberapa nilai dan amati seberapa cepat deadlock terjadi. Dan karena posisi duduknya melingkar. baru kemudian garpu kanan. JUMLAH_ILMUWAN dan WAKTU_FIKIR_MAKS adalah banyaknya ilmuwan yang ada dan waktu fikir ilmuwan seperti dijelaskan sebelumnya. dua objek Garpu akan dibuat. Setiap Ilmuwan diberi referensi ke garpu kiri dan garpu kanan. Di dalam metode makan(). Variabel ketiga DEADLOCK berupa boolean yang bisa berisi true atau false. (Seperti pada gambar berikut). mereka tidak akan makan secara bersamaan sehingga kemungkinan terjadinya deadlock menjadi lebih kecil. seorang ilmuwan akan mengambil garpu dengan melakukan sinkronisasi pada garpu tersebut. kecuali objek ilmuwan terakhir. maka ilmuwan tersebut akan menunggu hingga garpu selesai digunakan. Variabel statik waktuFikirMaks adalah waktu maksimum yang digunakan oleh ilmuwan untuk berfikir. mungkin saja pada suatu waktu semua ilmuwan akan makan dan saling menunggu garpu di sebelahnya. Setiap objek ilmuwan akan diberi garpu kiri dan kanannya. Objek pertama. yaitu WAKTU_TIMEOUT digunakan untuk menghentikan semua proses pada waktu tertentu. karena semua ilmuwan duduk pada posisi melingkar. Mula-mula garpu kiri dahulu yang dicoba untuk diambil. semua saling menunggu satu sama lain. Setiap kali. juga disimpan dalam variabel pertama akan digunakan kemudian. dan ilmuwan sebelahnya menunggu garpu sebelahnya lagi. garpu kanan akan dilepas terlebih dahulu baru kemudian garpu kiri.

Ilmuwan-ilmuwan kita adalah orang yang beradab. sehingga ilmuwan terakhir akan mengambil garpu kanan terlebih dahulu. Untuk ini saya mereferensikan Anda pada buku-buku teknik threading tingkat lanjut untuk lebih detailnya. Akan tetapi ini bukan satu-satunya pemecahan. Kesimpulannya. dan resume() pada kelas Thread. kita bisa memecahkannya dengan teknik yang lebih canggih. suspend(). sehingga tidak bisa merebut garpu yang sedang dipegang oleh ilmuwan lain. satu garpu bisa digunakan oleh dua orang ilmuwan 2.Untuk memecahkan masalah ini. dan seterusnya hingga proses terakhir menunggu sumber daya yang dipegang oleh proses pertama. baru kemudian garpu kiri. sehingga semua proses saling menunggu satu sama lain. Menghentikan Thread Salah satu perubahan pada Java 2 untuk mengurangi kemungkinan terjadinya deadlock adalah dengan dideprekasi (artinya pengembangannya dihentikan. Dalam hal ini. di mana proses pertama sedang menunggu satu sumber daya yang dipegang oleh proses kedua. kita harus mengerti bahwa deadlock bisa terjadi jika keempat kondisi berikut ini terjadi pada saat yang sama : 1. Java tidak menyediakan bantuan secara alami untuk mencegah deadlock: Anda harus menghindarinya sendiri dengan membuat program multi threading dengan lebih hati-hati. maka untuk mencegah terjadinya deadlock. lingkaran menunggu terjadi karena semua ilmuwan mengambil garpu kiri terlebih dahulu baru kemudian garpu kanan. Paling sedikit salah satu proses sedang memegang suatu sumber daya. Proses hanya bisa melepas sumber daya dalam kondisi normal. Dalam hal ini. Kita bisa memecahkan deadlock dengan membalik garpu kiri dan garpu kanan pada ilmuwan terakhir. Suatu sumber daya tidak bisa diambil secara paksa. kita harus memecah salah satu kondisi saja. cara termudah adalah dengan memecah kondisi keempat. dan di saat yang sama menunggu sumber daya lain yang dipegang oleh proses lain. 3. agar deadlock terjadi. yang juga sedang menunggu sumber daya yang dipegang oleh proses ketiga. dan user disarankan untuk menghindari penggunaannya) metode stop(). . seorang ilmuwan pasti sedang memegang satu garpu dan menunggu garpu lain yang dipegang oleh ilmuwan lain. Saling melarang (mutual exclusion): Paling sedikit salah satu sumber daya yang digunakan objek tidak boleh digunakan bersama. Lingkaran menunggu sedang terjadi. 4. Karena semua kondisi di atas harus terjadi secara bersama-sama agar deadlock bisa terjadi. Pada contoh ini. Pada program ini.

Berikut ini adalah contohnya : package com.Alasan mengapa metode stop() dideprekasi adalah karena metode ini tidak melepas kunci yang sudah dimilikinya.out.println(hitung++).hentikanthread. yaitu dengan mengeset suatu variabel untuk memberi tahu thread tersebut agar menghentikan dirinya sendiri yaitu dengan keluar dari metode run()-nya. private int hitung = 0.println("Permintaan stop dideteksi").out. Hasilnya akan muncul masalah yang tersembunyi yang akan sangat sulit dideteksi. Variabel ini akan dicek pada metode run() yang jika bernilai true.*. thread lain bisa melihat dan mengubah objek cacat ini. dan jika objek tersebut berada dalam kondisi "cacat" seperti ini. Java menyediakan cara lain untuk menghentikan thread. maka metode run() akan berhenti. blok ini tidak lagi dijalankan while (!stop && hitung < 10000) { System. } public void requestStop() { . import java.util. class Berhenti extends Thread { // Harus bertipe volatile: private volatile boolean stop = false.lyracc. public void run() { // Jika stop masih bernilai false teruskan cetak angka // Jika stop bernilai true. } // Jika stop berubah menjadi true if (stop) System.

println("Permintaan berhenti"). Tugas thread ini adalah mencetak 10000 angka. yang akan berhenti ketika hitung >= 10000 atau objek lain meminta berhenti dengan memanggil requestStop(). } } public class HentikanThread { /** * @param args */ public static void main(String[] args) { final Berhenti threadBaru = new Berhenti(). } }.schedule(new TimerTask() { public void run() { System. threadBaru.requestStop(). 500).out.start().stop = true. karena dilakukan dalam 1 clock). . new Timer(true). // run() setelah 500 mili detik } } Variabel stop harus bertipe volatile sehingga metode run() pasti bisa melihat variabel ini (jika tidak. Perhatikan bahwa requestStop() tidak synchronized karena stop bertipe boolean dan volatile (mengubah boolean menjadi [code]true adalah operasi atomis yang tidak bisa dihentikan di tengah jalan. maka nilainya bisa saja di-cache). threadBaru.

Misalnya.println("Memulai blokade").out. kita bisa menggunakan metode interrupt() pada kelas Thread untuk mengeluarkannya dari kondisi diblok. thread tersebut tidak bisa membaca variabel seperti kita lakukan di atas. } System. Timer dimulai untuk memanggil requestStop() setelah setengah detik (500 mili detik). start(). import java. package com. Konstruktor Timer diisi true untuk memastikan bahwa program berhenti saat itu juga. ketika thread dalam keadaan diblok (misalnya ketika sedang menunggu input).println("Keluar dari run()").interupsi. Menginterupsi Thread yang Diblok Kadang-kadang.Pada main(). Di sini.println("Diinterupsi").lyracc. } public void run() { try { synchronized (this) { wait().util. Pada saat yang sama.out.*. class ThreadDiblok extends Thread { public ThreadDiblok() { System.out. objek Berhenti dimulai. // Memblok selamanya } } catch (InterruptedException e) { System. } .

kita perlu melihat kilas balik tentang Java di awal perkembangannya. Kenapa IBM membuat sistem GUI lain dan tidak menggunakan rangka kerja GUI yang sudah ada pada Java? Untuk menjawab pertanyaan ini. /** * @param args */ public static void main(String[] args) { new Timer(true). Ketika Timer selesai.schedule(new TimerTask() { public void run() { System. threadDiBlok = null.} public class Interupsi { static ThreadDiblok threadDiBlok = new ThreadDiblok(). 2000). objek akan melakukan interupsi dengan memanggil interrupt().println("Bersiap-siap untuk interupsi"). // run() setelah 2 detik } } Panggilan wait() di dalam ThreadDiBlok. Kemudian objek threadDiBlok diset ke null sehingga bisa diambil oleh pemulung memori untuk dibersihkan. threadDiBlok.interrupt(). // buat null untuk diambil oleh pemulung memori } }.out. Pengenalan GUI dengan Eclipse SWT SWT adalah GUI berbagai platform yang dikembangkan oleh IBM. .run() akan memblok thread selamanya.

akan tetapi masalah lain muncul. Shell adalah jendela di mana aplikasi berjalan. yang memecahkan masalah yang terdapat pada rangka kerja AWT dan Swing. Misalnya. Masalah LCD ini mengakibatkan hilangnya beberapa fitur pada sistem operasi lain. Display bertugas untuk mengatur perulangan event (dari keyboard atau mouse) dan mengatur komunikasi antara thread UI dan thread lainnya. seperti tombol.25. Setiap aplikasi SWT memiliki paling tidak satu Display dan satu atau lebih instansi Shell. IBM membuat pustaka GUI baru yang disebut SWT. Rangka kerja SWT langsung mengakses widget bawaan sistem operasi melalui JNI. Shell dan kumpulan Widget adalah blok penyusun aplikasi SWT. dll) alami yang merupakan bawaan dari setiap sistem operasi.40 dan platform B memiliki widget 20 .Sun telah membuat rangka kerja GUI yang dinamakan AWT (Abstract Windowing Toolkit). Hal ini tidak ditemukan pada widget bawaan platform karena widget ini lebih dekat dengan sistem operasi. Lebih jauh. Akhirnya. aplikasi Swing menghabiskan lebih banyak memori yang tidak bisa digunakan untuk piranti kecil seperti PDA dan telepon genggam. bukan menggunakan widget bawaan platform. Dengan adanya perbaikan pada JVM. IBM memutuskan bahwa pendekatan tersebut tidak memenuhi kebutuhannya. maka rangka kerja AWT hanya bisa digunakan untuk sebagian widget yang beririsan saja. menu. aplikasi Swing tidak lagi mirip seperti aplikasi lain pada platform di mana ia dijalankan. Sun membuat rangka kerja baru yang merupakan emulasi widget. teks. Jika widget tersebut tidak tersedia. jika platform A memiliki widget 1 . maka SWT akan mengemulasi widget yang hilang itu. Blok Penyusun Suatu Aplikasi SWT Display. Akan tetapi widget tersebut memiliki masalah pada LCD. Hal ini memecahkan masalah LCD dan memberikan rangka kerja yang kaya widget. Atau dengan kata lain. aplikasi Swing tetap saja mengalami masalah kinerja karena sifatnya yang berupa emulasi. Untuk memecahkan masalah ini. . Rangka kerja AWT menggunakan widget (komponen pada GUI.

import ke dalam Eclipse seperti Anda mengimport proyek-proyek pada website ini.v3452b. Untuk ini Anda tidak perlu mendownload apa-apa. atau dikecilkan hingga tak terlihat. Ada dua jenis shell yang tersedia.x86_3. Beberapa sifat widget harus ditentukan pada saat widget tersebut dibuat. maka ia akan menjadi shell tingkat atas.4. misalnya pada Windows (C:\eclipse\plugins\org. kita bisa menggunakan SWT. Pilih Releases -> Stable -> (platform Anda.eclipse.Gambar di atas mengilustrasikan aplikasi SWT dari sudut pandang yang berbeda. Shell bisa ditampilkan dalam ukuran seluruh layar. Setelah diunduh.getCurrent(). maka shell yang dibuat akan bertipe DialogShell. Menggunakan pustaka SWT beserta sumber kodenya untuk dokumentasi lebih lengkap.PUSH | SWT. Pustaka SWT ini bisa diunduh pada alamat berikut : http://www. Suatu Shell melambangkan jendela suatu aplikasi. Jenis kedua adalah shell dialog yang bergantung pada shell-shell lainnya. Jenis suatu Shell bergantung pada bit gaya (style bit) yang diberikan pada konstruktornya. Diagram tengah adalah bagaimana objek UI diletakkan.linux. • Anda membutuhkan "link" ke pustaka SWT. Kita bisa mengambil instansi suatu objek Display dengan menggunakan metode statik Display. Sifat widget tersebut disebut bit gaya (style bit). Pustaka SWT bawaan eclipse terdapat pada direktori Eclipse Anda.swt. Misalnya. • • Memulai SWT Widget-widget SWT Memulai SWT Untuk memulai pemrograman dengan SWT.gtk. mari kita buat program sederhana yang kita namakan HelloSWT. Nilai awalnya adalah DialogShell. Bit gaya ini adalah konstanta yang didefinisikan dalam kelas SWT.BORDER sebagai parameter bit gayanya. Jika suatu aplikasi menggunakan beberapa thread. Menggunakan pustaka SWT bawaan dari Eclipse.1.eclipse.win32.jar) atau pada Linux (eclise/plugins/org.win32. yaitu dengan File -> Import -> General -> Existing Projects Into Workspace -> Select Archieve File -> (file zip SWT hasil download) -> Finish. ukuran biasa.x86_3. Button tombol = new Button(shell. bitGaya) Kita bisa menggunakan lebih dari satu gaya dengan menggunakan operator OR atau |.org/swt/. kita ingin membuat tombol yang bisa ditekan dan memiliki garis tepi.eclipse. Artinya. Yang pertama adalah shell dengan tingkat paling tinggi. Misalnya. setiap thread akan memiliki instansi objek Display masing-masing. Jika parameter konstruktornya berupa objek bertipe Display.4.jar) 2. Ada dua cara untuk melakukannya : 1. Langkah ini hanya dilakukan satu kali saja.v3449c. misalnya Windos atau Linux). dan gambar kanan adalah UI yang dihasilkan.swt. Diagram pertama di sebelah kiri adalah diagram kelas-kelas turunan dari objek-objek UI.1. yaitu yang dibuat langsung sebagai anak dari jendela utama Display. jika tidak ada parameter yang diberikan pada konstruktornya. .

Namanya tergantung dari sistem operasi Anda. pilih halaman Libraries.v3449c. Misalnya di komputer saya. . 1. Klik Add External JAR.win32. Klik OK setelah file ini ditambahkan di dalam folder Libraries. File -> New -> Java Project. Jika Anda menggunakan SWT bawaan Eclipse seperti di atas.win32.• Buat proyek baru dari Eclipse.eclipse.1. direktori itu berada di C:\eclipse\plugins. Pilih JAR untuk SWT pada direktori tersebut.4.x86_3. misalnya pada Windows file ini bernama org. kemudian isi Project Name dengan HelloSWT dan click Next • Kita harus menambahkan pustaka SWT ke dalam proyek kita.swt. kemudian navigasi ke direktori plugin di dalam instalasi Eclipse Anda.

swt.eclipse. kemudian tambahkan org. pilih halaman Projects. Klik Add.1. . Jika Anda mengunduh proyek SWT. Kemudian klik OK setelah proyek ini ditambahkan.

seperti pada gambar berikut. .• Folder proyek baru akan dibuat.

shell.setLayout( new RowLayout()).NONE). nama package dengan helloswt. dan pilih New -> Class. • Ketik kode berikut ini di dalam metode main() Display display = new Display(). Isi nama kelas dengan HelloSWT. . Label label = new Label(shell. Shell shell = new Shell(display). dan tik "public static void main(String[] args)" untuk membuat metode main() secara otomatis.• Kemudian klik kanan pada folder src. SWT.

NONE.swt.open().isDisposed()) if (!display.pack().widgets. Eclipse akan memberi tahu Anda kesalahan apa yang terjadi. Lihat sekarang di awal program Anda Eclipse menambahkan import org.swt. shell. kelas 'Display' belum diketahui oleh Eclipse. . Shell.readAndDispatch()) display. yaitu Shell.sleep().label.eclipse.setText("Hello.dispose(). shell. while (!shell. sehingga tidak ada lagi kesalahan yang dilaporkan oleh Eclipse.dispose(). Klik pada pilihan Import 'Display' (org. Sekarang pindahkan mouse Anda pada kesalahan pada kelas Display. RowLayout dan Label diberi tanda merah sebagai tanda bahwa kesalahan program terjadi. Pada contoh ini.Display. display. Label.eclipse. World!"). • • Perhatikan bahwa Display.widgets). secara otomatis. label. RowLayout dan SWT. • Lakukan hal yang sama pada semua kesalahan.

• • • • Mengkompilasi dan Membuat Program SWT Berjalan di Luar Eclipse Melihat Lebih Dekat HelloSWT Pengenalan Konsep Widget pada SWT Event dan Listener .• Untuk menjalankan program Anda. klik tombol Run seperti pada gambar berikut. • Berikut ini adalah tampilan program SWT pertama Anda.

Mari kita lihat contoh program HelloSWT yang sudah dibahas sebelumnya. (Misalnya. Kemudian pilih Runnable JAR File dari dalam folder Java.Mengkompilasi dan Membuat Program SWT Berjalan di Luar Eclipse Untuk bisa membuat program kita berguna untuk orang lain. yang menggabungkan semua file kelas yang sudah dikompilasi beserta pustaka yang dibutuhkan untuk bisa menjalankan program tersebut. kemudian pilih Export. di komputer saya proyek HelloSWT berada pada direktori C:\belajarjava. yaitu di mana data proyek ditempatkan. Pada Eclipse. Proses ini disebut menyebarkan (deploy). Eclipse akan meletakkan file JAR tersebut pada direktori di mana workspace berada. Pilih HelloSWT .lyracc. Untuk men-deploy program ini sehingga bisa dijalankan di luar Eclipse. Setelah itu kotak dialog akan terbuka.com\) .com\HelloSWT. Jika nama direktori tidak diberikan.lyracc. maka file JAR tersebut akan diletakkan pada direktori C:\belajarjava. program yang telah kita buat bisa kita deploy dalam format JAR (Java Archive). kita harus bisa mengkompilasi dan membuat program tersebut sebagai satu "paket".HelloSWT pada Launch configuration dan juga masukkan di mana file JAR hasilnya akan ditempatkan. lakukan langkah-langkah berikut : • • Klik kanan pada nama proyek Anda.

gunakan Windows Explorer untuk mencari di mana file JAR hasilnya berada. Anda bisa juga mengirimkan file ini melalui email atau mengkopinya melalui flash disk ke teman atau kerabat Anda tanpa perlu menyertakan Eclipse. Sekarang. .• Klik Finish. Double click pada file tersebut dan Anda akan bisa menjalankannya langsung seperti aplikasi lainnya. kemudian OK untuk setiap pertanyaan yang mungkin muncul berikutnya.

Untuk bisa menjalankannya pada sistem operasi lain. Anda menambahkan pustaka SWT yang spesifik terhadap sistem operasi di mana Eclipse berjalan.• • CATATAN : Ingat bahwa SWT bergantung penuh pada sistem operasi yang Anda gunakan.win32. maka Anda harus menambahkan pustaka SWT khusus Linux yang bisa diunduh secara terpisah atau menggunakan Eclipse pada Linux. karena SWT menggunakan widget bawaan sistem operasi seperti dijelaskan pada bagian sebelumnya.win32.swt.eclipse.4.x86_3. jika Anda menambahkan pustaka org. Artinya.v3449c. Ketika Anda membuat program ini pertama kali. Berikut ini adalah screen shot hasil jalannya program Melihat Lebih Dekat HelloSWT Secara umum aplikasi SWT membutuhkan beberapa langkah sebagai berikut : . misalnya Linux.1. maka program JAR Anda hanya akan bisa dijalankan pada sistem operasi Windows.

Label.widgets. Shell shell = new Shell(display). while (!shell.layout. import org.swt. import org. SWT.Display.widgets. public class HelloSWT { /** * @param args */ public static void main(String[] args) { Display display = new Display().1.swt.swt. import org.swt.Shell. Tentunya import berbagai paket yang diperlukan oleh program package helloswt.eclipse.eclipse.isDisposed()) . Buat satu atau lebih Shell 3. shell.pack(). Buat Display baru 2. import org. Label label = new Label(shell. label. Buang (dispose) display dan widget-widget lainnya 8.eclipse.setText("Hello. shell.setLayout( new RowLayout()).SWT. Buat widget di dalam shell 5. import org.widgets. shell. Buat perulangan pengirim event 7. Buat manager layout untuk Shell baru 4.eclipse. World!").NONE).eclipse.swt.open().RowLayout. Buka jendela shell 6.

akan tetapi komponen yang ditambahkan ke dalam tampilan dapat dilihat. Shell adalah jendela suatu aplikasi. Pada contoh di atas. 2. yaitu setLayout() yang mengambil parameter jenis layout yang akan disusun pada shell. Shell tertinggi adalah shell yang berada langsung di bawah objek bertipe Display. Oleh karenanya shell juga bisa berisi shell lain. Display (tampilan) adalah objek maya yang merupakan kontainer induk semua komponen GUI.dispose(). Membuat Display baru Membuat Display dapat dilakukan dengan membuat instansi dari objek bertipe Display. kita hanya membutuhkan satu shell saja yang kita letakkan pada objek display.sleep(). konstruktor Shell mengambil parameter yang merupakan induk di mana shell ini akan diletakkan. suatu aplikasi hanya membutuhkan satu tampilan. . Membuat Shell baru Membuat Shell dapat dilakukan dengan membuat instansi dari objek bertipe Shell.dispose(). misalnya seperti perintah berikut Shell shell = new Shell(display). yaitu suatu widget yang terdiri dari beberapa widget lain. shell. Pada pernyataan di atas. dan merupakan jendela utama suatu aplikasi. Suatu tampilan sebetulnya tidak terlihat. kita memerintahkan objek shell untuk mengatur widget-widget di dalamnya dalam urutan seperti baris. RowLayout adalah kelas layout yang digunakan objek shell untuk mengatur objek widget di dalamnya. kita menggunakan metode instansi dari objek shell. Membuat manager layout untuk Shell baru Untuk membuat manager layout. Misalnya.readAndDispatch()) display. } } Mari kita bahas satu per satu 1. kita membuat objek shell bertipe Shell yang memiliki induk objek display. label. Shell sebenarnya adalah widget komposit. Pada pernyataan di atas. 3. Untuk aplikasi sederhana yang menampilkan kata "Hello World!". misalnya seperti perintah berikut Display display = new Display(). display. Biasanya.setLayout( new RowLayout()).if (!display.

kita gunakan konstruktor yang mengambil 2 parameter. adalah contoh-contoh widget. .setText("Hello. adalah kontainer induk di mana Label ini akan ditampilkan. teks. kotak input teks. misalnya digunakan sebagai label atau pertanyaan pada suatu input teks. SWT. Pada SWT. 7. while (!shell. maka tanggung jawab untuk menghapus komponen GUI ada di tangan programmernya. dan karenanya kita akan bahas tersendiri pada bagian selanjutnya.NONE). Membuat perulangan pengirim event SWT mengharuskan kita untuk membuat sendiri perulangan untuk mengirimkan event.isDisposed()) if (!display. Widget ini digunakan untuk menampilkan teks. Hal ini disebabkan widget tersebut berada di luar jangkauan pemulung memori Java yang hanya bisa meraih objek yang dibuat dan dijalankan dalam JVM (Java Virtual Machine).open(). 6. 4. objek komposit seperti Shell tidak mengetahui bagaimana widget harus ditampilkan. Pada contoh ini. Artinya. label. hingga kanvas. Untuk ini kita gunakan perintah shell. tombol. Shell. World!"). Label ini kemudian kita isi dengan kata "Hello Word!" untuk menampilkan kata ini pada jendela utama. Menu. dan widget-widgetnya disiapkan.Manager layout digunakan untuk mengatur secara otomatis peletakkan setiap widget.readAndDispatch()) display. Oleh karenanya jika kita tidak memberikan manager layout kepada objek bertipe Shell. kita perlu secara eksplisit memerintahkan shell untuk membuka jendela dan menggambar seluruh widget yang sudah disiapkan. Membuka jendela shell Setelah Display. Pada contoh HelloSWT. maka tidak ada widget yang akan ditampilkan. dan parameter kedua adalah bit gaya. kotak cek.sleep(). Membuang (dispose) display dan widget-widget lainnya Karena SWT bekerja langsung dengan widget bawaan sistem operasi. 5. Membuat widget di dalam shell Widget adalah komponen pembangun GUI. Bahasan khusus tentang layout cukup kompleks. Yang pertama. blok perintah berikut ini "harus" selalu ada dalam semua aplikasi SWT yang akan kita buat. kita menggunakan widget yang sangat sederhana yang dinamakan Label. Label label = new Label(shell. Setiap widget memiliki sifat dan cara kerja yang berbeda-beda.

pendengar event.eclipse. dan kelas-kelas pengecualian dan kesalahan Widget dan kelas-kelas yang berhubungan dengannya.swt.swt. dan sebagainya Event tingkat tinggi.eclipse.eclipse.printing org. label.eclipse.eclipse.Untuk menghapus widget dari memori. tidak bergantung pada platform apapun (implementasinya sama pada semua sistem operasi) Kelas bantuan untuk melakukan drag-and-drop pada berbagai platform Perluasan untuk memberikan bantuan dan dukungan untuk orang cacat Dukugan printer dan kotak dialog untuk melakukan percetakan Berisi kelas Program.eclipse. dan kelas-kelas lainnya Huruf.swt.accessibility org. kita dapat menggunakan metode dispose() yang dimiliki oleh hampir semua widget SWT.eclipse. kelas super abstrak untuk layout. 8. yaitu shell dan label. warna.swt.widgets org.program . kita memiliki 2 widget.dispose(). pemetaan dokumen. sehingga keduanya harus dihapus dengan menggunakan perintah display. dukungan event. kotak dialog.eclipse. FormLayout.graphics org. dan icon. seperti untuk menggambar garis dan lingkaran Widget buatan sendiri dan kelas lain yang dibuat khusus untuk Eclipse.eclipse.eclipse. juga dibuat untuk Eclipse. kumpulan konstanta.eclipse.swt. Pada contoh program ini.custom org. dan operasi grafik dasar. dan colokan (adapter) Kelas layout standar seperti FillLayout. GridLayout.widgets. misalnya menu. RowLayout.dispose().swt. Mengimport berbagai paket yang diperlukan oleh program Kita bisa menggunakan Eclipse untuk membantu kita mengimpor setiap paket (seperti yang diilustrasikan pada bagian sebelumnya).swt. untuk mempermudah pada saat program dijalankan.events org. gambar. atau menggunakan wildcard seperti import org.swt.layout org.swt. akan tetapi sangat bergantung pada platformnya (implementasinya org.dnd org.swt Kegunaan Berisi kelas SWT.swt.* Beberapa paket penting yang tersedia pada SWT : Nama Paket org.

maka kita akan bahas lebih jauh pada bagian ini. baik diubah oleh user ataupun diubah oleh suatu kode program. Menggunakan browser bawaan sistem operasi untuk implementasinya Menyediakan dukungan untuk membuat UI yang berisi campuran widget dari SWT dan AWT Hanya tersedia pada Windows. SWT adalah kepanjangan dari Standard Widget Toolkit karena widget merupakan dasar pembangun suatu aplikasi yang dibangun dengan menggunakan SWT. kita dibolehkan untuk mengubah . Jenis induknya tergantung dari jenis widgetnya. widget akan mengambil sumber daya komputer (memori. Siklus hidup widget Widget memiliki siklus hidup sendiri.swt.ole Pengenalan Konsep Widget pada SWT Secara tradisional. (Pada beberapa platform.win32. dan tidak bisa berupa tombol. int bitGaya) Widget(Widget induk. kompiler akan menampilkan pesan kesalahan. Ketika widget dibuat. Ketika kondisi suatu widget berubah.eclipse. sehingga unjuk kerja dan pengaturan memori akan lebih optimal. menyediakan fasilitas untuk mengakses OLE (Object Linking and Embedding) org. Dengan menggunakan mouse atau keyboard. Widget mengatur dan menentukan kondisinya sendiri dengan memggunakan kombinasi beberapa operasi grafik. Misalnya. Widget dibuat oleh programmer dan dibuang ketika tidak lagi dibutuhkan. atau dengan kata lain membuat instansi suatu kelas. int bitGaya. Artinya semua widget akan berada di level sistem operasi. dan kelas-kelas yang mendukungnya. int posisi) Widget tidak bisa dibuat tanpa induk.eclipse. widget bisa dibayangkan seperti perangkat abstrak yang berguna untuk melakukan tugas tertentu. Ada 4 kemungkinan konstruktor dari suatu jenis widget : • • • • Widget() Widget(Widget induk) Widget(Widget induk. Konstruktor akan mengambil argumen yang biasanya tidak akan bisa diubah setelah widget dibuat. prosesor) dari sistem operasi. Istilah ini popules dalam bidan ekonomi.swt. 1. Kompiler akan mengecek apakah induk suatu widget sesuai dengan tipenya. Para pembuat software meminjam istilah ini untuk menyebut suatu paket program pembuat GUI (grahical user interface). induk dari suatu menu harus berupa menu.bisa berbeda untuk setiap sistem operasi) org. Ini bisa dilihat dari pengenalan tentang widget di bagian sebelumnya bagaimana widget tersusun secara hirarkis.eclipse.swt. user bisa mengubah kondisi suatu widget.awt org. Membuat Widget Widget dibuat dengan menggunakan konstruktornya. Karena siklus hidup suatu widget sangat penting untuk memahami SWT.browser Menyediakan widget sebagai web broswer. jika tidak. Apa itu widget? Widget adalah elemen GUI yang dapat berinteraksi dengan user. maka widget akan menggambar dirinya kembali untuk merefleksikan hasil perubahannya.

maka widget harus dihapus secara eksplisit dengan menggunakan metode instansi dispose().BORDER). maka hal ini akan menyebabkan kebocoran memori.println("teks tidak memiliki tepi").H_SCROLL | SWT. kemudian mencetak hasilnya pada konsol. Ini disebabkan karena kompleksitasnya yang mengharuskan kita untuk melakukan type cast kepada tipe induk yang benar. Memanggil metode dispose() untuk widget yang sudah dibuang.out.SWT. Gaya suatu widget bisa kita ambil setelah widget tersebut dibuat dengan menggunakan metode instansi getStyle(). Misalnya kode berikut akan membuat widget teks multi baris yang memiliki tepi serta scroll bar horizontal dan vertikal. Ada dua aturan yang penting untuk diingat : • Jika Anda membuat widget.MULTI | SWT. jika Anda menghapus menu utama. termasuk ketika program selesai. kode berikut menguji apakah suatu widget teks memiliki tepi.out. maka Anda tidak perlu menghapusnya • Jika Anda menghapus suatu widget.eclipse. akan melemparkan pengecualian SWTException. maka pastikan Anda menghapusnya. maka semua sub-menu akan otomatis dihapus. SWT. Text teks = new Text (induk. Atau dengan kata lain. Kita bisa menggambungkan beberapa gaya dengan menggunakan operasi OR. Semua gaya widget dikumpulkan sebagai konstanta pada kelas org. dan membuat semua referensi di dalamnya menjadi null. else System. semua widget yang Anda buat dengan konstruktor wajib dihapus. Biasanya bit gaya hanya dibutuhkan pada saat widget dibuat. maka gaya suatu widget juga tidak bisa diubah setelah widget diinstansikan. di mana memori pada sistem operasi lambat laun akan habis dipenuhi oleh widget yang tidak dihapus setelah program selesai.getStyle() & SWT.getFont(). Paremeter posisi memungkinkan kita membuat widget baru pada suatu induk di posisi tertentu. Atau dengan kata lain. Metode ini akan menyembunyikan widget. menghapus widget yang ditampungnya. Untuk mengujinya. maka semua widget di bawahnya akan dihapus juga. Hal ini akan lebih memudahkan kita untuk membuat widget pada urutan tertentu. if ((teks.BORDER) != 0) System. jika Anda menghapus suatu Shell. Misalnya.println("teks memiliki tepi"). misalnya memilih jenis editor multi baris atau baris tunggal. Demikian juga halnya dengan menu. Jika tidak diberikan. misalnya membuat menu dengan urutan tertentu.) Bit gaya (style) adalah nilai bit integer yang digunakan untuk mengatur perilaku dan tampilan suatu widget.induk suatu widget. maka secara otomatis widget baru akan ditempatkan di akhir posisi.swt. Karena atribut ini tidak bisa diubah setelah widget dibuat. 2. misalnya Font huruf = kontrol. kita bisa menggunakan metode instansi isDisposed().V_SCROLL | SWT. Jika metode dispose() tidak dipanggil setelah program selesai dijalankan. Untuk mengetahui apakah suatu widget sudah dihapus. kita bisa menggunakan operasi AND yang jika hasilnya tidak nol. maka isi seluruh Shell akan dihapus secara otomatis. Akan tetapi jika Anda mendapatkan widget dari metode instansi suatu widget. Membuang widget Ketika widget tidak lagi dibutuhkan. Event dan Listener . Akan tetapi SWT tidak memiliki metode getParent() pada kelas-kelas Widgetnya. maka widget tersebut memiliki gaya yang diuji.

Pada SWT kita harus menulis sendiri perulangan event ini pada metode main() kita dalam bentuk while (!shell. Setelah objek event dibuat. Event tanpa tipe diwakili oleh kelas Event. User bisa melakukannya kapan saja. Akan tetapi. Ketika suatu event terjadi.isDisposed()) if (!display. kemudian membuat objek yang berisi informasi ini. sistem akan mengumpulkan informasi yang sesuai dengan even tersebut. User bisa menekan tombol keyboard apa saja. yaitu event tanpa tipe dan event bertipe. program harus bisa bereaksi akan berbagai event (kejadian) yang bisa berasal dari mouse atau keyboard. Kelas ini menyimpan informasi yang berbeda-beda tergantung dari jenis.readAndDispatch()) display. Dengan menulis subrutin ini. kita hanya melihat even dari sisi yang lebih umum. Dalam Java. misalnya. Secara garis besar. programmer bisa memberi tahu apa yang harus dilakukan jika mouse diklik atau keyboard ditekan. Akan tetapi secara umum semua event jenis apapun memiliki informasi berikut : Informasi Penjelasan display widget type Display di mana event ini terjadi Widget di mana event ini terjadi Jenis event yang terjadi . SWT memiliki dua jenis event.sleep(). ia akan diberikan sebagai parameter pada subrutin yang ditugaskan untuk menangani event tersebut. GUI program tidak memiliki alur apa yang akan terjadi ketika program dijalankan.Event Event adalah inti dari pemrograman GUI. event dilambangkan oleh objek. dalam metode main() kita harus menuliskan perulangan dalam bentuk seperti : ketika program masih berjalan: Tunggu hingga even berikutnya terjadi Panggil subrutin untuk menangai event tersebut Perulangan ini disebut perulangan event. Banyak sekali hal yang terjadi antara tombol ditekan hingga subrutin yang kita buat melakukan tugasnya. dalam arti langkah per langkah dari awal hingga akhir. atau menekan tombol mouse. Sebagai programmer Java. Jenis even berbeda dilambangkan oleh objek dengan kelas yang berbeda pula. menggeser mouse. dan komputer harus bisa bereaksi dengan tepat.

Resize SWT.Paint SWT.KeyUp SWT.FocusOut SWT.MouseDoubleClick Mouse di-double click SWT.MouseEnter SWT.Expand SWT.Move SWT.MouseExit Penjelasan Tombol ditekan Tombol dilepaskan Tombol mouse ditekan Tombol mouse dilepaskan Mouse berpindah posisi Mouse masuk ke wilayah klien Mouse berada di sekitar klien Mouse keluar dari wilayah klien SWT.Jenis event yang terjadi beserta penjelasannya dirangkum dalam tabel berikut ini : Jenis Event SWT.MouseMove SWT.Close Suatu widget diberi perintah untuk menggambar dirinya Posisi suatu widget berubah Ukuran widget berubah Widget dihapus Suatu aksi pemilihan dilakukan dalam widget (misalnya memilih item pada drop down list Ada pilihan awal pada suatu widget Widget menerima fokus dari keyboard Widget kehilangan fokus dari keyboard Item pada pohon dikembangkan Item pada pohon ditutup Jendela Shell diminimasi Jendela Shell dibuka (restore) Jendela Shell ditutup (dengan tombol X) .DefaultSelection SWT.Collapse SWT.MouseDown SWT.Selection SWT.FocusIn SWT.MouseUp SWT.MouseHover SWT.Iconify SWT.Deiconify SWT.KeyDown SWT.Dispose SWT.

eclipse.Resize DisposeEvent SWT.SWT.Dispose FocusEvent SWT.MenuDetect SWT.HardKeyUp Widget bisa dilihat Widget disembunyikan Teks berubah pada suatu kontrol Input teks sedang diverifikasi Widget sedang diaktifkan Widget dimatikan User meminta pertolongan tentang suatu widget Aksi drag-and-drop dideteksi User menekan tombol kik kanan untuk mengaktifkan menu konteks Item pada menu digambarkan Navigasi pada keyboard dideteksi Tombol pada hardware ditekan (untuk perangkat genggam) Tombol pada hardware dilepas (untuk perangkat genggam) Suatu event juga bisa memiliki tipe.DragDetect SWT. Artinya event yang dihasilkan merupakan objek bertipe suatu kelas. Event Bertipe ArmEvent ControlEvent Jenis Event Tanpa Tipe SWT.HardKeyDown SWT.Traverse SWT.Move SWT.Arm SWT.events Tabel berikut menggambarkan perbandingan antara event bertipe dan jenis event dari event tanpa tipe. bukan hanya bertipe kelas Event yang jenisnya disimpan dalam variabel tertentu.FocusOut .Modify SWT.swt.Deactivate SWT.Help SWT. Kelas-kelas ini terdapat dalam paket org. Event bertipe mengikuti pola JavaBeans standar.Hide SWT.Arm SWT.Show SWT.FocusIn SWT.Verify SWT.Activate SWT. misalnya MouseEvent.

Deiconify TraverseEvent SWT.MouseEnter MouseEvent SWT.Selection SWT.Help SWT.MouseDoubleClick MouseEvent SWT.Expand SWT.Traverse SWT.Modify SWT.MouseExit SWT.Hide SWT.MouseDown SWT.Collapse TreeEvent VerifyEvent SWT.Iconify SWT.MouseUp MouseEvent SWT.Deactivate SWT.Activate SWT.KeyDown SWT.MouseMove SWT.HelpEvent KeyEvent SWT.MouseHover PaintEvent SelectionEvent SWT.Verify Pertanyannya kenapa ada dua jenis event yang berbeda? .Paint SWT.Show MenuEvent ModifyEvent SWT.Close ShellEvent SWT.KeyUp SWT.DefaultSelection SWT.

misalnya "org. Aksi ini adalah aksi yang dilakukan untuk menangani suatu event 4. Menambahkan import paket yang dibutuhkan. Mendeklarasikan kelas yang mengimplementasikan interface suatu listener 3.Pada versi awal SWT. Mendengarkan event ini dilakukan oleh objek yang berna. Listener Supaya suatu event berarti. Suatu kelas dapat dibuat secara khusus hanya untuk mendengarkan suatu event. maka akhirnya diputuskan untuk menambahkan jenis bertipe seperti pada JavaBeans. Objek apapun bisa bertindah sebagai event listener asalkan ia mengimplementasikan interface yang tepat.events" 2. .a pendengar event (event listener). suatu program harus bisa mendeteksi event dan bereaksi akan event tersebut. SWT memiliki dua jenis listener : tanpa tipe dan bertipe. Mendaftarkan event tersebut ke komponen yang mungkin memberikan event. Listener listener) Metode ini akan menambah listener ke dalam koleksi listener yang akan dipanggil ketika event tipe tertentu terjadi. (Kelas bertingkat anonim telah dibahas sebelumnya di sini).eclipse. Seperti hanya Event. Setelah diskusi yang cukup antar beberapa programmer Eclipse. Listener Tanpa Tipe (untuk menangani event tanpa tipe) nterface generik yang digunakan untuk menangai event tanpa tipe dinamakan Listener. Bentuknya bervariasi tergantung dari jenis event yang ditanganinya. hanya ada satu jenis yaitu jenis tanpa tipe. Untuk mendeteksi suatu event. maka listener akan dipanggil dengan menggunakan metode handleEvent(). Menambahkan aksi yang dilakukan oleh kelas baru tersebut. Kebanyakan orang menganggap lebih mudah untuk menggunakan kelas bertingkat anonim untuk mendengarkan suatu objek. Listener tanpa tipe dapat ditambahkan pada suatu widget dengan menggunakan metode addListener(). komunitas user SWT dan developernya. Objek listener harus memiliki metode instansi untuk menangani event yang didengarkannya.swt. Ketika suatu event terjadi. Jenis tanpa tipe masih tetap ada seperti biasa. Masing-masing digunakan untuk menangani event tanpa tipe dan event bertipe. Metode addListener() memiliki bentuk seperti addListener(int jenisEvent. Alasannya adalah untuk memudahkan pemrograman SWT bagi programmer yang sudah terlanjur terbiasa dengan AWT/Swing. suatu program harus mendengarkannya. Suatu komponen dapat mendengarkan event yang dihasilkannya sendiri. Beberapa langkah yang harus diingat : 1. Ada beberapa hal detail yang harus diingat untuk bisa bekerja dengan event.

JIka beberapa instansi listener yang sama sudah ditambahkan sebelumnya. new Listener() { public void handleEvent(Event event) { // widget was disposed } }). Secara umum. maka mereka akan dipanggil dengan urutan ketika mereka ditambahkan (first in first called). dan Event adalah objek yang berisi event yang akan dilakukan.addListener(SWT. Event event) jenisEvent adalah jenis event yang akan dilakukan. Di dalam kelas anonim tersebut. yang memiliki bentuk seperti notifyListeners(int jenisEvent. di mana implementasinya adalah tugas yang harus dilakukan ketika widget dihapus.Dispose terjadi. yaitu dengan menggunakan metode notifyListeners. yang akan dipanggil ketika event SWT. Jika beberapa listener ditambahkan. metode handleEvent() harus diimplementasikan. Hal penting yang harus dicatat adalah memanggil metode notifyListeners() tidak menyebabkan event akan benar-benar terjadi. Kita bisa menghapus listener dari suatu widget dengan menggunakan metode removeListener().Contoh berikut mengilustrasikan bagaimana menambah suatu Listener ke dalam suatu widget. Artinya listener pertama diberi kesempatan untuk mengolah event (mungkin untuk memfilter sejumlah data) sebelum listener lain melakukan tugasnya. yang artinya listener tersebut akan dipanggil beberapa kali. Dan juga memanggil notifyListeners() tidak menjamin bahwa semua data pada event terinisialisasi seperti pada event sesungguhnya.Dispose. Kita juga bisa memanggil suatu listener untuk melakukan tugas tertentu. Listener listener) Untuk menghapus suatu listener. Kita juga bisa menambah listener yang sama beberapa kali. Bentuknya adalah sebagai berikut removeListener(int jenisEvent. Listener akan diambil oleh pemulung memori ketika suatu widget dihapus dan listener ini tidak lagi digunakan di manapun di dalam program. widget. maka kita harus menghapusnya berulang kali sejumlah ia ditambahkan. Listener Bertipe (untuk menangani Event bertipe) . menghapus suatu listener mungkin tidak diperlukan. Misalnya memanggil notifyListeners() dengan jenis SWT.MouseDown tidak akan menyebabkan tombol terlihat seperti ditekan. kita harus memberikan instansi yang persisi sama ketika listener tersebut ditambahkan. Perhatikan bahwa bentuk di atas menggunakan kelas anonim yang langsung diturunkan dari interface Listener.

maka SWT akan secara otomatis menambahkan kelas adapter yang berisi implementasi kosong dari metode-metode yang didefinisikan pada interface tersebut. Potongan kode berikut digunakan untuk menangani event ketika suatu widget dihapus. Misalnya. Event Bertipe Interface Listener ArmEvent ArmListener Metode widgetArmed(ArmEvent) Jenis Event Tanpa Tipe SWT. listener untuk event ketika suatu widget dihapus bisa dibuang dengan menggunakan removeDisposeListener(). Listener bertipe bisa dihapus dengan menggunakan metode penghapus untuk setiap listner. dibandingkan dengan listener tanpa tipe. Misalnya interface SelectionListener memiliki dua metode. nama interface listener yang menanganinya. yang keduanya mengambil argumen bertipe SelectionEvents. yaitu widgetSelected() dan widgetDefaultSelected. yang memiliki bentuk removeDisposeListener(DisposeListener listener) listener adalah objek listener yang akan dihapus dari koleksi listener yang dipanggil ketika widget dihapus. serta metode pada interface tersebut.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent event) { // widget was disposed } }). yang memiliki bentuk seperti addDisposeListener(DisposeListener listener) Metode ini menambahkan listener ke dalam koleksi listener yang akan dipanggil ketike suatu widget dihapus.Arm . DisposeListener adalah suatu interface. Tabel berikut merangkum event bertipe. Jika ada lebih dari satu metode yang didefinisikan dalam listener. Ketika suatu widget dihapus. Dalam hal ini kelas SelectionAdapter tersedia untuk memberikan implementasi kosong untuk setiap metode. penggunaan listener bertipe sangat mirip dengan penggunaan listener pada AWT/Swing. maka listener akan dipanggil dengan memanggil metode widgetDisposed(). Misalnya untuk mendengarkan event ketika suatu widget dihapus. maka aplikasi bisa menggunakan addDisposeListener(). Kelas adapter ini hanyalah sebagai kelas bantu yang sesuai dengan konvensi pada listener JavaBeans.Karena event bertipe dibuat mengikuti pola listener pada JavaBeans. widget.

MouseHover SWT.Paint FocusListener (dan focusGained(FocusEvent) FocusAdapter) focusLost(FocusEvent) HelpListener KeyListener (dan KeyAdapter) helpRequested(HelpEvent) keyPressed(KeyEvent) keyReleased(keyEvent) MenuEvent ModifyEvent MenuListener (dan menuHidden(MenuEvent) MenuAdapter) menuShown(MenuEvent) ModifyListener modifyText(ModifyEvent) mouseDoubleClick(MouseEvent) MouseEvent MouseListener (dan mouseDown(MouseEvent) MouseAdapter) mouseUp(MouseEvent) MouseEvent MouseMoveListene mouseMove(MouseEvent) r MouseTrackListene mouseEnter(MouseEvent) r (dan mouseExit(MouseEvent) MouseTrackAdapte r) mouseHover(MouseEvent) PaintListener paintControl(PaintEvent) MouseEvent PaintEvent SelectionListener SelectionEven (dan t SelectionAdapter) widgetDefaultSelected(SelectionEve SWT.ControlListener ControlEvent (dan ControlAdapter) DisposeEvent DisposeListener FocusEvent HelpEvent KeyEvent controlMoved(ControlEvent) controlResized(ControlEvent) widgetDisposed(DisposeEvent) SWT.MouseExit SWT.Show SWT.Dispose SWT.KeyDown SWT.MouseMove SWT.MouseDoubleClic k SWT.FocusOut SWT.Activate SWT.Resize SWT.MouseUp SWT.Hide SWT.Modify SWT.MouseEnter SWT.Close SWT.KeyUp SWT.MouseDown SWT.FocusIn SWT.DefaultSelection nt) widgetSelected(SelectionEvent) shellActivated(ShellEvent) SWT.Help SWT.Deactivate ShellEvent ShallListener (dan ShellAdapter) shellClosed(ShellEvent) shellDeactivated(ShellEvent) .Move SWT.Selection SWT.

klik. . Perilaku "drag-and-drop" mouse kurang lebih sangat bergantung pada platformnya. yang tidak membutuhkan kursor. widget teks akan mengubah tampilan kursor seperti huruf I untuk menunjukkan bahwa user bisa mengetikkan sesuatu pada widget tersebut. atau jenis perangkat keras lainnya. Pengambilan mouse terhadi secara otomatis pada SWT. walaupun sebenarnya mouse lebih dari 1 tombol pun bisa digunakan).Expand SWT.Verify keyTraversed(TraverseEvent) treeCollapsed(TreeEvent) treeExpanded(TreeEvent) verifyText(VerifyEvent) TreeListener (dan TreeAdapter) VerifyListener Penanganan Mouse Penanganan Keyboard Penanganan Mouse Semua sistem operasi di mana SWT diimplementasikan mendukung perangkat tunjuk. Mouse digunakan untuk menunjuk. Akan tetapi ketika tombol mouse ditekan dan ditahan (terus ditekan). (Ini mungkin bukan sesuatu masalah. kursor akan berbah bentuk.Collapse SWT.Deiconify SWT. Event pada Mouse Ketika tombol mouse ditekan atau mouse digerakkan. ada titik pusat yang menunjukkan koordinat x dan y suatu mouse ketika event pada mouse terjadi. Posisi suatu mouse biasanya digambarkan dalam bentuk ikon kecil pada layar yang disebut kursor. Mouse biasanya memiliki tiga tombol (kecuali pada Macintosh yang hanya memiliki satu tombol. trackpad. Untuk mempermudah pembahasan. Widget yang menerima event disebut widget pengambil. kita akan gunakan mouse sebagai perangkat tunjuk. akan tetapi bisa jadi berupa trackball. tergantung dari kontrol apa di bawahnya. Pengalihan event sementara ini disebut pengambilan mouse. geser (drag) dan memilih komponen kontrol GUI. akan tetapi sebagai informasi saja kepada Anda). Pada komputer genggam. Misalnya. Hal ini berlaku untuk semua platform. karena perangkat Windows CE biasanya berupa perangkat tunjuk "langsung". Di dalam kursor.shellIconified(ShellEvent) shellDeiconified(ShellEvent) TraverseEvent TraverseListener TreeEvent VerifyEvent • • SWT. kecuali pada Windows CE. event mouse dibuat dan akan diberikan kepada widget yang ada di bawahnya. Bisa juga digunakan untuk menampilkan menu konteks yang biasanya ditampilkan dengan mengklik kanan suatu mouse. tidak peduli bagaimana perangkat aslinya. dan mouse berada di luar widget (mungkin ada di widget lain atau pada aplikasi lain di desktop). seperti stylys.Iconify SWT. perangkat tunjuk bisa jadi berupa stylus. Biasanya berbentuk mouse. eventnya akan diberikan kepada widget awal di mana mouse tersebut ditekan. Ketika kita menggeser mouse.Traverse SWT.

stateMask berisi keadaan mouse sebelum terjadinya suatu event. Hal ini untuk menghindari program kita untuk bertindak terlalu sensitif terhadap pergerakan mouse. field bernama "button" akan diisi oleh tombol mana yang ditekan. karena dilakukan secara otomatis oleh sistem operasi. Karena user mungkin telah memindahkan mouse setelah menekan tombol. event dan listener SWT terdiri dari event/listener tanpa tipe dan event/listener bertipe.Isi Event Mouse ketika suatu tombol mouse ditekan. Koordinat yang dilaporkan adalah koordinat relatif widget ketika event tersebut dibuat (bukan koordinat global layar atau aplikasi kita). Ketika terjadi event pada mouse. stateMask tidak berisi "tombol 1". dilepaskan atau mouse digeser Nama Field Penjelasan button x y stateMask Tombol yang ditekan atau dilepaskan Koordinat x ketika event terjadi Koordinat y ketika event terjadi Bit mask yang menyatakan kondisi keyboard dan mouse sebelum event terjadi Ketika mouse ditekan atau dilepas. kita bisa menggunakan metode getCursorLocation() yang dimiliki oleh kelas Display.BUTTON2 SWT. maka event mouse akan diisi dengan button bernilai 1 dan stateMask bernilai 0. koordinat x dan y-nya juga dilaporkan dalam event.BUTTON_MASK Bitwise-OR dari tombol-tombol yang ditekan Berikut ini adalah event pada mouse yang disediakan oleh SWT. (Jika kita membutuhkan lokasi yang aktual pada saat-saat tertentu. Seperti disebutkan pada bagian sebelumnya. Akan tetapi ketika terjadi event lain ketika mouse kiri sedang ditekan.BUTTON3 Penjelasan Tombol 1 ditekan Tombol 2 ditekan Tombol 3 ditekan SWT. Seperti pada penanda tombol. Untuk user kidal (dan mengkonfigurasi sistem operasi untuk orang kidal). akan tetapi dimulai dari kanan ke kiri. Keduanya disarikan dalam tabel berikut : . Pemetaan tombol untuk orang kidal ini tidak tampak oleh SWT dan aplikasi kita. Misalnya. maka lokasi sebenarnya ketika event ini ditangani mungkin berbeda dengan ketika event dibuat. seperti pada tabel berikut : stateMask SWT.Tabel . penomoran tombol tetap sama.) Event pada mouse juga menggunakan field lain yang dinamakan stateMask untuk menunjukkan keadaan mouse. Keadaan suatu mouse dilambangkan oleh konstanta pada kelas SWT. maka stateMask akan berisi 1. Tombol mouse diberi nomor dari kiri ke kanan yang dimulai dari 1. jika tidak ada tombol mouse yang ditekan atau tombol keyboard lain yang ditekan ketika tombol kiri mouse ditekan.BUTTON1 SWT.

MouseDown mouseUp(MouseEvent) SWT. .MouseDoubleCli double ent) ck click MouseListener MouseEven (dan t MouseAdapter) Tombol mouse ditekan Tombol mouse dilepaskan Mouse berpindah posisi Mouse masuk ke wilayah klien Mouse berada di sekitar klien Mouse keluar dari wilayah klien mouseDown(MouseEvent) SWT.MouseExit mouseHover(MouseEvent) SWT. Anda bisa mengunduh program ini dan mengimportnya pada Eclipse di sini.MouseMove mouseEnter(MouseEvent) SWT.*.eclipse.MouseHover Mari kita lihat contoh penggunaan mouse event pada program berikut.MouseEnter MouseTrackListen MouseEven er (dan mouseExit(MouseEvent) t MouseTrackAdapt er) SWT.lyracc. package net.*.MouseUp MouseEven MouseMoveListen mouseMove(MouseEvent) t er SWT.swt.widgets.eclipse. import org.pelacakmouse. import org.Kelas Event (event bertipe) Interface/Kelas Listener (listener bertipe) Metode (listener bertipe) Jenis event (event tanpa tipe) Penjelasan Mouse dimouseDoubleClick(MouseEv SWT.swt.

MouseEnter: output="ENTER". break. case SWT. // Kelas Listener baru. break. break. break.MouseMove: output = "MOVE". case SWT. case SWT. break.MouseDown: output = "DOWN". break. Shell shell = new Shell(display). menggunakan listener tanpa tipe Listener mouseListener = new Listener() { // metode handleEvent pada interface Listener harus diimplementasikan public void handleEvent(Event e) { String output = "UNKNOWN".MouseDoubleClick: output = "DOUBLE". case SWT.type) { case SWT.MouseUp: output = "UP". case SWT. . switch (e.MouseExit: output = "EXIT".public class PelacakMouse { /** * @param args */ public static void main(String[] args) { // Membuat display dan shell baru Display display = new Display().

SHIFT) != 0) output += " SHIFT".MouseHover: output="HOVER". kemudian menampilkannya // dalam bentuk heksadesimal output += ": stateMask=0x" + Integer. // Jika tombol Command ditekan. // Jika tombol kiri mouse ditekan.stateMask & SWT.stateMask & SWT.stateMask). } // Mengambil stateMask pada event.stateMask & SWT. // Jika tombol Ctrl ditekan. tambahkan SHIFT pada keluarannya if ((e. tambahkan CTRL pada keluarannya if ((e. // Jika tombol Shift ditekan. tambahkan BUTTON1 pada keluarannya if ((e. tambahkan ALT pada keluarannya if ((e.COMMAND) != 0) output += " COMMAND".CTRL) != 0) output += " CTRL".ALT) != 0) output += " ALT".stateMask & SWT.toHexString(e.case SWT. // Jika tombol Alt ditekan. tambahkan COMMAND pada keluarannya if ((e.stateMask & SWT. break.BUTTON1) != 0) .

out. } }. tambahkan BUTTON3 pada keluarannya if ((e. . // Mengambil koordinat x dan y output += ".x + ".println(output).MouseDown.stateMask & SWT.button). mouseListener).toHexString(e. // Jika tombol tengah mouse ditekan.addListener(SWT. button=0x" + Integer.stateMask & SWT. tambahkan BUTTON2 pada keluarannya if ((e. // Tambahkan listener pada setiap event yang ingin kita pantau shell. y=" + e. // Jika tombol kanan mouse ditekan.y.BUTTON2) != 0) output += " BUTTON2". // Menampilkan pesan keluaran pada konsol System.output += " BUTTON1". x=" + e. // Mengambil field button pada event.BUTTON3) != 0) output += " BUTTON3". kemudian menampilkannya // dalam bentuk heksadesimal output += ".

isDisposed()) if (!display. Setelah jendela aplikasi yang kita buat keluar.sleep(). shell.addListener(SWT. mouseListener). mouseListener). shell.dispose(). mouseListener). harus ada pada setiap aplikasi SWT shell. Jangan lupa untuk menambahkan pustaka SWT sebelum menjalankan program ini seperti dibahas pada bagian ini. shell.addListener(SWT. Klik Run pada Eclipse dan jalankan sebagai Java Application.readAndDispatch()) display.addListener(SWT.shell.MouseUp. 200).addListener(SWT. } } Program di atas akan melacak aktivitas mouse kemudian menampilkannya pada konsol. shell. display.MouseExit. mouseListener).MouseMove. // Ubah ukuran jendela menjadi 200 x 200 piksel shell.MouseEnter.addListener(SWT. mouseListener).MouseHover. mouseListener).MouseDoubleClick. while (!shell.addListener(SWT. // Perintah "standar" SWT. . coba jalankan mouse dan perhatikan "Console" pada Eclipse seperti gambar berikut.setSize(200. shell.open().

maka event yang dihasilkan akan diberikan kepada widget yang ada dibawahnya. Jika ada menu konteks. kontrol tersebut akan mengolah karakter dan menampilkannya. Ketika user menekan tombol pada mouse. tombol yang dimasukkan diproses oleh IME sehingga user bisa memasukkan karakter Kanji. Metode input. kebanyakan kontrol (widget yang bisa berinteraksi dengan user) bisa menangani keyboard tanpa perlu campur tangan aplikasi. Tugasnya untuk mengubah urutan tombol keyboard menjadi karakter yang bisa dibaca sesuai dengan konfigurasi locale usernya. adalah mesin pengolah karakter yang disediakan oleh setiap sistem operasi. Misalnya. atau sering juga disebut IM (input method) atau IME (input method engine). maka menu ini akan secara otomatis disediakan. 2. Sistem jendela Akselerator untuk menu Traversal Kontrol fokus . 3. karakter bisa dimasukkan dengan cara yang berbeda. 4. pada locale Jepang. ketika user memasukkan karakter Kanji pada kontrol teks. tombol tersebut akan diberikan kepada subsistem berikut dalam urutan : 1. Bahkan untuk platform yang sama tetapi dengan versi sistem operasi atau kedaerahan (locale) yang berbeda.Penanganan Keyboard Membuat API yang bisa dijalankan di berbagai platform untuk mengakses keyboard bukan sesuatu yang mudah. Untungnya. Apa yang terjadi ketika tombol keyboard di tekan? Komponen mana yang harus menangani event yang dihasilkan? Ketika suatu tombol pada keyboard ditekan. Misalnya.

biasanya tidak mengambil fokus. Mungkin merupakan sesuatu yang baik untuk memberi user sedikit bantuan untuk mengetahui apakah suatu komponen memiliki fokus input.Artinya setiap subsistem diberi kesempatan untuk bereaksi terhadap tombol keyboard. Misalnya. Suatu kontrol tidak bisa mengambil fokus jika ia tidak aktif atau disembunyikan. Dalam hal ini kita sebut tombol tersebut telah digunakan.setFocus(). maka biasanya kursornya akan berubah menjadi bentuk I dan berkedip-kedip. mulai dari kontrol fokus. fungsi ini akan mengembalikan true. input teks yang sedang dalam fokus memiliki warna latar belakang yang berbeda dengan input teks yang tidak memiliki fokus. Kita juga bisa mencari tahu kontrol mana yang sedang memiliki fokus dengan menggunakan metode pada kelas Display yaitu Display. Kelas Event Interface/Kelas Metode (listener bertipe) Jenis event Penjelasan . Jika kontrol atau salah satu komponen yang ditampungnya berhasil mengambil fokus. Kita akan diskusikan setiap subsistem dari bawah ke atas. seperti label. maka tombol ini tidak akan diteruskan ke subsistem berikutnya. dalam urutan seperti di atas. yaitu di mana semua event dari keyboard akan diarahkan. kita bisa menggunakan metode setFocus() yang terdapat pada hampir semua widget. Pada suatu saat. Untuk memberikan fokus kepada suatu komponen. maka sukses = kontrol. karena konsep ini adalah konsep dasar yang diperlukan dalam pemrograman GUI. jika komponen tersebut adalah tempat mengetik pada program pengolah kata. Contoh lainnya adalah misalnya dalam suatu formulir. memberi perintah kepada kontrol untuk mencoba mengambil fokus input.isFocusControl() mengembalikan true jika kontrol tersebut sedang memegang fokus atau false jika tidak. Widget komposit (yaitu widget yang bisa berisi widget-widget lain) akan berusaha untuk memberi fokus kepada widget yang ditampungnya sebelum mengambil fokus untuk dirinya sendiri. Berikut ini adalah daftar event dan listener yang berkaitan dengan fokus. maka false akan dikembalikan. Beberapa widget lain. Jika kontrol adalah objek bertipe suatu widget yang bisa menerima fokus dan sukses adalah variabel bertipe boolean. Jika gagal. Jika salah satu subsistem mampu menangani tombol tersebut. hanya ada elemen pada layar yang bisa menerima input.getFocusControl(). • • • Kontrol Fokus Traversal Tombol Akselerator dan Tombol Sistem Jendela Kontrol Fokus Program GUI menggunakan fokus input untuk menentukan komponen mana yang yang harus menangani event dari keyboard. atau jika input diblokade karena modalitas (atau karena kontrol lain tidak mengijinkan fokus berpindah tempat). Fungsi lain kontrol.

(event bertipe)

Listener (listener bertipe)

(event tanpa tipe) Widget menerima fokus dari keyboard Widget kehilangan fokus dari keyboard

focusGained(FocusEvent) SWT.FocusIn FocusEvent FocusListener (dan FocusAdapter) focusLost(FocusEvent) SWT.FocusOut

Mari kita lihat contoh berikut ini untuk memahami lebih lanjut tentang fokus input. Kita akan buat 2 widget yang berupa input teks. Ketika input teks atas menerima fokus, maka judul aplikasi kita ganti dengan "Fokus pada input teks atas". Ketika input teks bawah menerima fokus, maka judul aplikasi kita ganti dengan "Fokus pada input teks bawah". Jika input teks atas kehilangan fokus, kita isi input teks yang kehilangan fokus dengan "Saya kehilangan fokus", begitu input teks atas menerima fokus kembali, kita akan hapus kalimat tersebut.

Contoh program ini dapat Anda unduh di sini, untuk diimport pada Eclipse. Pembahasan detail tentang contoh program ini akan dibahas kemudian. Event pada Tombol Ketika suatu tombol pada keyboard ditekan, event tombol akan dibuat dan diberikan kepada aplikasi kita. Akan tetapi, tergantung pada platformnya, kedaerahan (locale), dan kombinasi tombol, ada kalanya event tidak terjadi. Misalnya, pada karakter Eropa yang memiliki aksen, mesin pengolah karakter dari sistem operasi akan mengambil tombol tersebut untuk diolah. Misalnya pada kedaerahan Jerman jika karakter ^ ditekan kemudian diikuti dengan tombol e, maka karakter ê akan ditampilkan. Demikian juga jika tombol bantu ditekan untuk mengolah bahasa Jepang, IME akan mengolah urutan karakter menjadi karakter Kanji. Dengan kata lain, event tingkat rendah seperti ini sangat bergantung pada platform dan sistem operasi, sehingga tidak terlalu berguna untuk kebanyakan program. SWT menyembunyikan event sistem operasi dan hanya menampilkan satu event tombol saja setelah sistem operasi selesai mengolah tombol tersebut.

Berikut ini adalah daftar event dan listener yang berkaitan dengan tombol. Interface/Kelas Kelas Event Listener (listener (event bertipe) bertipe) Jenis event (event Penjelasan tanpa tipe) Tombol ditekan Tombol dilepaskan

Metode (listener bertipe)

keyPressed(KeyEvent) KeyEvent KeyListener (dan KeyAdapter)

SWT.KeyDown

keyReleased(keyEvent) SWT.KeyUp

Event SWT.KeyDown dan SWT.KeyUp merupakan representasi tingkat tinggi dari tombol yang ditekan dan dilepaskan. Event-event ini berguna jika kita ingin mencegat suatu tombol tertentu dan melakukan aksi khusus ketika tombol itu ditekan. Berikut ini adalah isi event keyboard ketika ditekan/dilepaskan. Nama Field Penjelasan character keyCode stateMask doit Nilai Unicode dari karakter yang ditekan Konstanta yang menunjukkan tombol mana yang ditekan, misalnya SWT.PAGE_UP Melambangkan tombol tambahan, misalnya SWT.SHIFT Suatu boolean yang bisa digunakan untuk membatalkan aksi penekanan tombol

character berisi karakter yang kita masukkan lewat keyboard setelah diolah oleh sistem operasi. Misalnya jika kita menekan tombol <a> maka character berisi 'a'. Jika tombol <Shift> dan <a> ditekan, maka character berisi 'A'. Jika tombol <Ctrl> dan <a> ditekan, maka character akan diisi karakter yang bersesuaian dengan Ctrl+a, yaitu karakter dengan kode Unicode '\u0001' (atau SOH). Beberapa tombol seperti Enter, Backspace, Tab, memiliki kode karakter Unicode tersendiri. SWT juga memiliki konstanta untuk mewakili tombol-tombol ini, yaitu Konstanta character SWT.BS SWT.CR SWT.DEL SWT.ESC SWT.LF Penjelasan Tombol backspace Tombol Enter Tombol Del Tombol Esc Tombol LF

SWT.TAB

Tombol Tab

keyCode berisi karakter yang tidak bisa diwakilkan dengan karakter Unicode, misalnya tombol <F1>, tombol <PgUp>, tombol <Panah Atas>, dan lain-lain termasuk tombol angka pada keypad dan tombol <+> <-> <*> pada keypad. Beberapa tombol tersebut dilambangkan dalam konstanta sebagai berikut. Khusus untuk keypad, apabila tombol <+> ditekan, maka selain keyCode berisi SWT.KEYPADD_ADD, character juga berisi '+'. SWT.F1 SWT.F11 SWT.F2 SWT.F12 SWT.PAGE_DOWN SWT.HOME SWT.KEYPAD_ SWT.KEYPAD_EQUA 0 L SWT.KEYPAD_ SWT.KEYPAD_CR 1 SWT.KEYPAD_ SWT.HELP 2 SWT.KEYPAD_ SWT.CAPS_LOCK 3

SWT.F3 SWT.F13 SWT.F4 SWT.F14

SWT.END SWT.INSERT

SWT.F5 SWT.F15 SWT.F6 SWT.ARROW_UP

SWT.KEYPAD_MULTIPL SWT.KEYPAD_ SWT.NUM_LOCK Y 4 SWT.KEYPAD_ADD SWT.KEYPAD_ SWT.SCROLL_LOCK 5

SWT.F7

SWT.ARROW_DOW SWT.KEYPAD_SUBTRA SWT.KEYPAD_ SWT.PAUSE N CT 6 SWT.KEYPAD_ SWT.BREAK 7 SWT.KEYPAD_ SWT.PRINT_SCREE 8 N SWT.KEYPAD_ 9

SWT.F8 SWT.ARROW_LEFT SWT.KEYPAD_DECIMAL SWT.ARROW_RIGH SWT.KEYPAD_DIVIDE T SWT.KEYPAD_0

SWT.F9

SWT.F10 SWT.PAGE_UP

stateMask berisi tombol sebelum tombol ditekan, yang biasanya <Ctrl>, <Shift>, <Alt>, <Command>. Pada kebanyakan keyboard hanya ada 3 tombol pertama, akan tetapi ada juga yang memiliki lebih dari 3 tombol. Tombol-tombol ini disebut tombol pengubah. SWT membuat tombol-tombol ini menjadi kode seperti stateMask SWT.MOD1 Penjelasan Tombol pengubah pertama ditekan (biasanya SWT.CONTROL pada

Windows atau SWT.COMMAND pada Macintosh) SWT.MOD2 SWT.MOD3 SWT.MOD4 Tombol pengubah kedua ditekan (biasanya SWT.SHIFT) Tombol pengubah ketiga ditekan (biasanya SWT.ALT) Tombol pengubah keempat ditekan (biasanya 0)

SWT.MODIFIER_MASK Gabungan dari keempatnya (menggunakan bitwise OR) Dengan representasi seperti ini, maka SWT bisa dijalankan pada beberapa platform, dan tidak bergantung dengan tombol apa yang ada pada suatu sistem operasi. Bayangkan jika Anda ingin menggunakan <Control> + <b> untuk membuat karakter menjadi tebal, akan tetapi tombol <Control> tidak tersedia pada Macintosh. Untuk menguji tombol pengubah mana yang ditekan, kita bisa menggunakan bitwise AND, misalnya (e.stateMask & SWT.SHIFT). Berikut ini adalah contoh program pelacak keyboard yang akan melaporkan tombol apa yang Anda tekan dan lepaskan. Contoh program ini dapat Anda unduh di sini untuk mengimportnya ke dalam Eclipse. Jalankan program ini pada Eclipse, kemudian ketik apa saja di program Anda, perhatikan "Console" di Eclipse akan penuh dengan berbagai laporan tentang tombol yang ditekan dan dilepaskan.

Kadang kala dalam kondisi yang sangat langka, kita harus mengolah sendiri tombol kita sebelum diolah oleh suatu wudget. Karena SWT menggunakan widget bawaan sistem operasi, pengolahan tombol terjadi di level sistem operasi. Misalnya, ketika user mengetik pada widget teks, listener SWT.KeyDown akan dijalankan, kemudian sistem operasi akan memasukkan karakter dan menggambarnya kembali dijalankan oleh sistem operasi. Dengan menggunakan doit, kita bisa membuang karakter tersebut untuk tidak meneruskannya ke sistem operasi. Contoh berikut akan menghalangi user untuk memasukkan karakter pada widget teks dengan mengeset doit menjadi false setiap kali event SWT.KeyDown terjadi. package com.lyracc.penghalangtombol;

import org.eclipse.swt.*; import org.eclipse.swt.widgets.*;

public class PenghalangTombol {

/** * @param args */ public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); Text text = new Text(shell, SWT.SINGLE | SWT.BORDER);

text.addListener(SWT.KeyDown, new Listener() { public void handleEvent(Event event) { event.doit = false; } });

text.pack(); shell.pack();

shell.open(); while (!shell.isDisposed()) if (!display.readAndDispatch()) display.sleep(); display.dispose(); } }

Traversal
Traversal atau penelusuran berarti memindahkan fokus dari satu kontrol ke kontrol lain. Tombol traversal berbeda dengan tombol akselerasi dan tombol sistem jendela (yang akan dibahas nanti), yaitu : Suatu kontrol bebas memilih apakah akan menjalankan operasi traversal atau mengolah tombol yang ditekan. Jika kontrol memilih untuk menjalankan operasi traversal maka tombol tersebut tidak akan diproses lebih lanjut. Ada dua jenis traversal, yaitu mnemonik dan tab. Traversal Mnemonik Mnemonik biasanya tertulis sebagai karakter yang diberi garis bawah pada label suatu widget. Suatu aksi akan dilakukan jika user menekan kombinasi tombol yang cocok dengan mnemonik tersebut, biasanya dengan menekan tombol <Alt> bersamaan dengan karakter yang digaris bawah tersebut. Gambar berikut adalah contoh mnemonik pada program OpenOffice ketika kita membuka kotak dialog Format Font

Jika kita menekan <Alt> + H maka tampilan Help akan ditampilkan. Menekan tombol kombinasi untuk memanggil mnemonik sama dengan mengaktifkan widget tersebut. Pada contoh di atas, mnemonik <Alt> + H diterapkan pada tombol, yang artinya ketika kita menekan <Alt> + H, sama dengan kita menekan tombol Help. Beberapa widget yang tidak bisa menerima pilihan, seperti label dan kotak grup masih bisa menerima mnemonik, akan tetapi fungsinya hanya untuk memindahkan fokus ke widget tersebut. Bagaimana caranya menambahkan mnemonik? Mudah saja. Cukup tambahkan '&' di depan karakter yang akan kita tandai sebagai mnemonik, kemudian masukkan string ini sebagai argumen pada metode setText() suatu widget. Misalnya pada perintah berikut : Button tombol1 = new Button(shell, SWT.PUSH); tombol1.setText("&Klik saya"); akan membuat tombol dengan mnemonik <Alt> + K, seperti pada gambar berikut ini :

Tidak seperti pada mnemonik. isi detail SWT. Berikut ini adalah daftar event dan listener yang berkaitan dengan traversal. Nama traversal tab mungkin agak sedikit salah sasaran. Ketika sampai pada widget terakhir. Misalnya. Pada beberapa platform. Beberapa tombol lain seperti <Esc> digunakan untuk menutup kotak dialog. gunakan '&&'.Untuk membuat mnemonik pada karakter '&' sendiri. maka fokus akan otomatis pindah ke widget berikutnya. Interface/Kelas Kelas Event Listener (listener (event bertipe) bertipe) Jenis event (event tanpa tipe) Metode (listener bertipe) Penjelasan TraverseEvent TraverseListener Navigasi pada keyTraversed(TraverseEvent) SWT. karena setiap platform memiliki cara sendiri bagaimana memindahkan fokus dari satu widget ke widget lain. ketika kita menekan tombol <Tab>. menekan tombol panah juga memindahkan fokus. . karena sepertinya hanya tombol <Tab> saja yang bisa digunakan untuk memindahkan fokus dari satu widget ke widget lain.Traverse keyboard dideteksi Berikut ini adalah isi event ketika event traversal terjadi. misalnya "Ini && Itu" akan menghasilkan "Ini & Itu" Traversal Tab Traversal tab didukung pada semua platform. dan sebenarnya termasuk dalam tombol traversal tab juga.TRAVERSE_ESCAPE Penjelasan Traversal yang terjadi ditutupnya suatu kotak dialog. kita tidak perlu mendefinisikan apa-apa. maka fokus akan diulang dari widget pertama. pada traversal tab. Nama Field Penjelasan detail doit Detail traversal yang terjadi Suatu boolean yang bisa digunakan untuk membatalkan aksi traversal detail berisi salah satu dari nilai-nilai berikut.

Akan tetapi.TRAVERSE_NONE maka widget tidak akan melakukan traversal. traversal akan dilakukan dan tombol akan "dikonsumsi" (tidak diberikan kepada widget untuk diproses kembali). Apa yang terjadi jika detail juga diisi dengan SWT. doit digunakan untuk membatalkan traversal jika variabel ini diisi false. Artinya jika event doit kita isi dengan true.TRAVERSE_ARROW_PREVIOUS SWT. .TRAVERSE_NONE? Jika detail diisi dengan SWT. variabel doit menentukan apakah tombol akan diberikan kepada widget untuk diproses. Akan tetapi lihat bahwa pada variabel detail juga bisa SWT.misalnya dengan menekan tombol Cancel atau tombol <Esc> SWT.TRAVERSE_MNEMONIC SWT. Misalnya kita ingin mengubah tombol <Enter> bukan untuk menutup dialog akan tetapi untuk memindahkan fokus ke widget lain.TRAVERSE_PAGE_PREVIOUS SWT.TRAVERSE_TAB_PREVIOUS SWT.TRAVERSE_NONE Variabel detail bukan hanya untuk dibaca akan tetapi kita juga bisa mengisinya apabila kita ingin mengubah jenis traversal.TRAVERSE_NONE.TRAVERSE_PAGE_NEXT SWT.TRAVERSE_RETURN Traversal yang terjadi ketika kotak dialog selesai diisi misalnya setelah menekan tombol OK atau tombol <Enter> Traversal yang terjadi ketika fokus pindah ke group tab sebelumnya Traversal yang terjadi ketika fokus pindah ke group tab sesudahnya Traversal yang terjadi ketika fokus pindah ke item sebelumnya Traversal yang terjadi ketika fokus pindah ke item sesudahnya Traversal mnemonik terjadi Traversal yang terjadi ketika untuk pindah ke halaman sebelumnya pada kotak dialog Traversal yang terjadi ketika untuk pindah ke halaman berikutnya pada kotak dialog Traversal tidak terjadi SWT. kita bisa mengisi variabel detail dengan SWT.TRAVERSE_TAB_NEXT SWT. tidak peduli apakah isi doit berisi true atau false.TRAVERSE_ARROW_NEXT SWT. Jika doit kita isi denga false. traversal tidak dilakukan dan tombol akan diberikan kepada widget untuk diproses.TRAVERSE_ARROW_PREVIOUS. Apa perbedaannya? Ingat bahwa tombol yang tidak digunakan untuk traversal akan diberikan kepada widget yang menerima traversal untuk diolah lebih lanjut.

package com.*. Ketika Anda melewati tombol 4 atau tombol 6. maka tombol akan diberikan kepada widget. yang bisa diunduh di sini. Coba tekan tombol <Tab>. maka traversal tidak dilakukan. .swt.eclipse. Program lengkapnya adalah sebagai berikut.TRAVERSE_NONE. Jika Anda menekan tombol <Shift> + <Tab> fokus akan berpindah ke tombol sebelumnya.Jadi jika doit berisi false dan detail berisi SWT. Pada saat yang sama di konsol akan tercetak "Anda tidak bisa kembali!". akan tercetak "Button {4} ditelusuri".TRAVERSE_NONE. Akibatnya Anda tidak akan bisa pindah dari tombol 4 ke tombol 3 atau tombol 6 ke tombol 5. Akan tetapi jika Anda sampai pada tombol 4 atau tombol 6. dan tombol akan dikonsumsi dan tidak akan diberikan kepada widget. import org. event traversal yang terjadi akan ditangkap dan traversal akan diabaikan. Akan tetapi jika doit berisi true dan detail berisi SWT.lyracc.traversalkustom. Program ini akan membuat 6 tombol. Fokus akan pindah ke tombol berikutnya setiap kali Anda menekan tombol <Tab>. Berikut ini adalah contoh penggunaan traversal. dan traversal tidak dilakukan.

50.setBounds(10.100.PUSH). b1.events.100. b1.50). shell. b6. Button b6 = new Button(shell. 200).swt.50.10.setBounds(200. SWT. Button b2 = new Button(shell.*.setBounds(200. b2. Button b5 = new Button(shell. b5. Shell shell = new Shell(display).setBounds(10.100. public class TraversalKustom { /** * @param args */ public static void main(String[] args) { Display display = new Display().50).setBounds(100. SWT.PUSH).PUSH).setText("1").eclipse.eclipse. import org. . Button b4 = new Button(shell. Button b1 = new Button(shell.setBounds(100. SWT.*.10.10.50).50. SWT.50. b3.swt.50.PUSH). b4.50).setSize(300. SWT.50).PUSH).PUSH).widgets.import org. SWT.50. Button b3 = new Button(shell.50).

setText("2").sleep().setText("5").widget + " ditelusuri"). e. b3.out.readAndDispatch()) display.addTraverseListener(traverseListener). b4.detail == SWT. TraverseListener traverseListener = new TraverseListener() { public void keyTraversed(TraverseEvent e) { if (e. shell.setText("6"). } } .println(e. b5.TRAVERSE_TAB_PREVIOUS) { System.addTraverseListener(traverseListener).isDisposed()) if (!display.out. b4. while (!shell. display. } System.setText("3"). b6.b2.setText("4").open().doit = false.dispose(). b6.println("Anda tidak bisa kembali!"). } }.

MOD1 + 'S' Rangkaian Tombol <Ctrl> + <A> <Shift> + tombol panah ke atas Tombol pengubah pertama (biasanya <Ctrl> atau <Command>) + <S> SWT. <Shift>. misalnya pada Firefox. isi kodeAkselerator dengan 0. Ketika akselerator dipanggil.MOD1 + SWT. <Alt>) dan satu tombol lain yang berupa karakter atau keyCode (seperti tanda panah. Akselerator direpresentasikan pada SWT dalam bentuk kode integer tertentu. dll).MOD2 + 'B' Tombol pengubah pertama + Tombol pengubah kedua + <B> Akselerator diberikan kepada menu atau toolbar dengan menggunakan metode setAccelerator(int kodeAkselerator) di mana kodeAkselerator adalah kode akselerator seperti dicontohkan pada tabel di atas. sehingga akselerator bersifat global. Kode integer tersebut berisi gabungan beberapa tombol. yaitu tombol pengubah (seperti <Ctrl>. Untuk mereset akselerator. maka potongan kode berikut akan menambahkan akselerator pada item tersebut : . Berikut ini adalah beberapa contoh akselerator. F1 hingga F15.Tombol Akselerator dan Tombol Sistem Jendela Tombol Akselerator Akselerator adalah tombol shortcut ke salah satu menu. misalnya pada kebanyakan program pengolah kata menekan tombol <Ctrl> dan S artinya menyimpan teks yang sedang diedit. Akselerator selalu berhubungan dengan menu.ARROW_UP SWT. Akselerator SWT. Lihat bahasan tentang fokus kontrol untuk mengerti lebih jauh tentang bagaimana penanganan tombol pada SWT. Tombol akselerator tidak bisa hanya terdiri dari tombol pengubah saja. Misalnya jika item adalah suatu item pada menu. maka tombol-tombol yang ditekan akan dikonsumsi langsung oleh aplikasi dan tidak diberikan kepada widget apa-apa. bisa 2 tombol seperti contoh <Ctrl> di atas atau mungkin lebih. tombol <Ctrl> + <Shift> + J membuka konsol kesalahan (error console). Untuk mengambil tombol akselerator suatu menu atau toolbar bisa digunakan dengan menggunakan metode getAccelerator() yang mengembalikan nilai integer. yang berarti kita bisa menekan tombol akselerator dari dalam widget manapun yang sedang aktif pada saat itu. Akselerator biasanya berupa rangkaian tombol yang ditekan bersamaan. <Esc>.SHIFT + SWT.CONTROL + 'A' SWT.

Berikut ini adalah metode-metode yang dimiliki oleh seluruh widget turunan dari kelas abstrak Widget yang mencakup hampir seluruh widget SWT. new Listener() { public void handleEvent(Event e) { System. Perlu dicatat bahwa hanya menambahkan teks akselerator pada metode setText() tidak membuat tombol akselerator otomatis ditambahkan dalam metode setAccelerator().println("Item dipilih. akan tetapi SWT akan mengganti tampilan Ctrl-S menjadi Tombol Sistem Jendela Tombol yang diproses oleh sistem jendela tidak akan sampai pada aplikasi kita. Manager jendela akan melakukan aksi terlebih dahulu dan tombol tersebut akan dikonsumsi oleh manager jendela. -S. Karena tidak adanya kesamaan pada setiap manager jendela. <!-. Karakter '\t' di dalam setText memberi tahu SWT bahwa karakter setelah itu adalah tombol akseleratornya. Kelas ini adalah kelas abstrak yang tidak bisa langsung diinstansiasi. .@page { margin: 0. Tombol-tombol mana yang akan dimanage oleh manager jendela berbeda-beda. tombol <Ctrl> tidak ada pada Macintosh.out. Misalnya pada contoh di atas. tergantung dari sistem jendela tersebut.79in } TD P { margin-bottom: 0in } P { margin-bottom: 0.addListener(SWT.MOD1 + 'S'). maka kita tidak bisa mencegat penekenan tombol ini misalnya dialihkan untuk melakukan fungsi lain. Kelas Widget merepresentasikan semua objek user interface.08in } --> Widget-widget SWT Pada bagian ini akan kita bahas widget-widget yang disediakan oleh SWT.setText("Pilih &Semua\tCtrl+S"). tombol Alt-F4 pada beberapa sistem akan menutup jendela yang aktid. Pada Linux misalnya manager jendela bisa bermacammacam. Manager jendela tidak sama dengan sistem operasi.").setAccelerator(SWT.item. Misalnya. Pada Windows. misalnya KDE dan Gnome.Selection. item. manager jendela itu terintegrasi dengan sistem operasi. item. Menambahkan teks akselerator pada setText() berfungsi untuk membetulkan kesalahan yang terjadi jika tombol akselerator tidak terdapat pada platform yang dituju. } }).

Mengembalikan Object yang merupakan data tambahan ke suatu widget. Mengembalikan true jika widget ini sudah dihapus dari memori Menambahkan data tambahan (terserah kita) ke dalam suatu widget. yang memiliki kunci key Mengembalikan int yang merupakan bit gaya suatu widget. Object o) getData(String key) getStyle() Event ini terdapat pada semua kelas turunan dari kelas abstrak Widget Interface/Kelas Kelas Event Listener (listener (event bertipe) bertipe) DisposeEvent DisposeListener Jenis event (event tanpa Penjelasan tipe) SWT. Data ini tidak akan ditampilkan pada widget. getData() setData(String key. Objek yang tidak memiliki induk (atau induknya bertipe Display) disebut shell tingkat paling tinggi. akan lebih mudah jika kita menandai data tersebut dengan suatu kunci key.Dispose Widget dihapus Metode (listener bertipe) widgetDisposed(DisposeEvent) • • • • • Shell Kotak Dialog Dasar-dasar Kontrol dan Label Button (Tombol) Text Shell Objek bertipe Shell adalah suatu jendela pada aplikasi. Data ini disebut data aplikasi. • • Bit Gaya Shell Metode pada Shell .Metode dispose() isDisposed() setData(Object o) Penjelasan Menghapus widget dari memori. Data ini tidak akan ditampilkan pada widget. Mengembalikan Object yang merupakan data yang bisa kita tambahkan ke dalam widget Jika kita akan menambahkan banyak data ke dalam objek. Objek yang memiliki induk yang berupa shell lain disebut shell sekunder atau shell dialog.

• Event pada Shell Bit Gaya Shell .

Sign up to vote on this title
UsefulNot useful