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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

System. g = y .Instalasi. System.com/svn/trunk/OperatorAritmatika Lihat cara mengimpor contoh-contoh program ke dalam Eclipse di Bab II . % Operator sisa pembagian n = n % 1. g = x + y.Operator pengurangan * Operator perkalian / Operator pembagian % Operator sisa pembagian Operator aritmatika digunakan untuk melakukan operasi matematika. g = z % y. / Operator pembagian n = n / 1.out.googlecode. g = x * y. 0.out.println("Sisa pembagian (z%x) : " + g).println("Pengurangan (y-x) : " + g). 5. .out. pembagian. 3. Contoh penggunaan : Simbol Nama operator Contoh penggunaan + Operator penjumlahan n = n + 1.out. dan modulo (atau sisa pembagian). seperti penambahan. pengurangan.Operator Aritmatika + Operator penjumlahan (juga sebagai penyambung string) . System.println("Perkalian (x*y) : " + g). * Operator perkalian n = n * 1.println("Penjumlahan (x+y) : " + g). Contoh kode program yang dapat Anda unduh dalam bentuk zip file atau melalui SVN di alamat berikut : http://belajarjava. package operatoraritmatika. System.println("Pembagian (y/x) : " + g).x. 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.1. System. + Operator penyambung string n = "saya "+"tidur". g = y / x. Operator pengurangan n = n .

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

ok = !true. System. int y = 0. sedangkan apabila diletakkan di akhir (x++ atau x--) penambahan/pengurangan dilakukan setelahnya. Operator kenaikan dan penurunan dapat diletakkan di belakang atau di depan suatu variabel. angka = --angka.println("Nilai y = ++x : " + y).out. System. System.println("\nContoh operator pada sufix (akhiran)"). Jika diletakkan di depan (++x atau --x). // sekarang angka bernilai 1 angka = ++angka.googlecode.println("---------------------------"). y = x++. package operatortunggal. System.++ -! Operator minus Operator kenaikan Operator penurunan Operator lawan menyatakan nilai negatif.out.Instalasi. public class OperatorTunggal { /** * Contoh program menggunakan operator tunggal * * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int x = 0.out.println("Nilai x baru :" + x).out. System. System. System. angka = -angka.println("Nilai x baru : " + x).out.println("Nilai y = x++ :" + y). 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.out. 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.out. x = 0.println("---------------------------").out. Walau bagaimanapun pada akhirnya keduanya akan menghasilkan x = x+1 atau x = x-1.println("Contoh operator pada prefix (awalan)").com/svn/trunk/OperatorTunggal Lihat cara mengimpor contoh-contoh program ke dalam Eclipse di Bab II . y = ++x. } } . System. penambahan/pengurangan dilakukan sebelumnya.

dalam hal ini operasinya dilakukan pada dua operand. nilai "y" adalah nilai "x" terdahulu. maka nilai "x" dan "y" akan sama. gunakan equals(). 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).Jalankan program tersebut dan lihat hasilnya. Berikut ini adalah screenshot keluarannya : Operator Pembanding. equalsIgnoreCase(). dan compareTo() seperti dibahas pada bagian sebelumnya. operasi pembanding akan membandingkan alamat memory tempat objek itu disimpan. bukan membandingkan isinya. seperti String. Untuk membandingkan isi String. Apabila operator ++ diletakkan di awal (prefix). Java akan memberi nilai "y" dengan nilai "x" sebelum operasi ++ dilakukan. karena penambahan nilai "x" dilakukan terlebih dahulu. sedangkan Operator Pembanding membandingkan 2 nilai seperti pada operasi matematika. Simbol Nama operator Contoh . Apabila operator ++ diletakkan di akhir (sufix). Catatan : Pada objek. lalu hasilnya diberi kepada "y". Baru kemudian nilai "x" ditambahkan.

Operator kondisi OR Operator kondisi OR menghasilkan "true" jika salah satu operandnya bernilai "true". apabila Op1 (di sebelah kiri) bernilai "false". Berikut ini table kebenaran oeprasi OR. b = (1 >= 2). hasilnya akan selalu "false" tidak tergantung pada isi dari Op2. b = (1 <= 2). Berikut ini tabel kebenaran operasi AND. Op1 Hasil true false . apabila Op1 (di sebelah kiri) bernilai "true". Operator NOT Operator NOT ("!") melakukan operasi boolean NOT pada operand atau ekspresi tunggal. 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". Seperti terlihat dari tabel di atas. Berikut ini adalah tabel kebenaran operator NOT. b = (1 > 2). b = true && false. 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". hasilnya akan selalu "true" tidak tergantung pada isi dari Op2. b = !true. Operator ini mengecek nilai boolean dari suatu operand atau expresi kemudian membalik nilainya (dari true ke false atau false ke true). Jika salah satunya atau keduanya "false". b = (1 < 2). operator ini menghasilkan "false". b = true || 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 boolean AND Operator kondisi AND menghasilkan "true" apabila kedua operandnya bernilai "true". Jika keduanya "false". operator ini menghasilkan "false". Seperti terlihat dari tabel di atas.

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

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

Operator += -= *= /= %= &= |= ^= < <= >>= >>>= Contoh x += y. x = (x * y). System. x = (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. Contoh kode program yang dapat Anda unduh dalam bentuk zip file atau melalui SVN di alamat berikut : http://belajarjava. x ^= y.com/svn/trunk/OperatorPemberiNilai package operatorpemberinilai. x >>= y.out. x = (x >> y).println("Hasil pembagian : " + x). System.println("Hasil operasi AND : " + x). x = (x < < y). x -= y.out. int y = 10. x = (x >>> y). x &= y.y). x < <= y.println("Hasil pengurangan : " + x). System. x *= y. . x += y. x = (x ^ y). System.out. x = (x % y). x %= y. x %= y.println("Hasil perkalian : " + x). x -= y. x /= y. x |= y.println("Hasil penjumlahan : " + x). x /= y. System.out. x *= y. x >>>= y.googlecode.println("Hasil operasi OR : " + x).out. x &= y.out. System. x = (x / y).println("Sisa pembagian : " + x). System. x |= y. x = (x . Ekspresi setara x = (x + y).out. x = (x | y).

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

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

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

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

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

// tempat di mana input dari user akan diletakkan String nama = null. double bunga. strawal = br. // tampilkan hasil perhitungan di layar System.out. try { System. nama = br.print("Masukkan nama Anda : "). } catch(IOException ioe) { System.pow(1+bunga.readLine().out.println("Terima kasih. System.exit(1). " + akhir). System.out.readLine(). // mengubah input dari Sting ke tipe data bilangan periode = Integer. .println("Kesalahan IO pada saat menanyakan } System. bunga = Double.out.out. String strperiode = null. awal = Double. int periode. System.in)).out.print("Masukkan bunga (mis 0. // deklarasi variabel tipe bilangan double awal./** * @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.out. strbunga = br. String strbunga = null. System.parseDouble(strbunga).print("Masukkan jumlah awal investasi (Rp) : "). tahun "). String strawal = null.out.out. nama Anda").println(). strperiode = br.parseInt(strperiode). " + nama).readLine(). double akhir. periode). // menghitung hasil investasi selama n periode akhir = awal * Math.print("Hasil investasi Anda setelah " + periode + " System. System.1 = 10%) : ").println("adalah Rp.readLine().parseDouble(strawal).print("Masukkan periode (tahun) : ").

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

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

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

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

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

untuk mengambil input user. 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. 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. kita memiliki suatu tugas di kepala. kita ambil contoh untuk menghitung rata-rata dari 5 bilangan. Bagaimana jika bilangan yang akan dirata-ratakan ada 100? Kita bisa udah algoritma di atas dengan pseudocode yang lebih mudah dimengerti. sampai kita bisa menerjemahkan langkah-langkah itu ke dalam bahasa pemrograman.Di bagian ini akan dibahas tentang bagaimana membuat suatu algoritma. Misalnya. Jadi bahasa Java akan kita tinggalkan sementara. Selain itu kita juga harus menginisialisasi pembaca dan tempat meletakkan string sementara. Kemudian dari setiap langkah tersebut. dan sifatnya top-down atau dari atas ke bawah. Kita akan beralih untuk berfikir secara abstrak. Salah satu cara untuk menyelesaikan tugas itu adalah menuliskan penyelesaiannya langkah demi langkah. kita harus mengubah pseudocode nya menjadi seperti ini inisialisasi pembaca . Sambil kita menambah detail pada setiap langkah. tetapi terlalu banyak perulangan. dan dari sana kita membuat algoritma untuk menyelesaikan masalah itu. kita bisa mulai menuliskan algoritma dalam bentuk pseudocode (kode palsu) yang bentuknya tidak harus persis atau mengikuti suatu bahasa pemrograman. Untuk itu. ambil input user bisa dideskripsikan lebih jauh. kita bisa membuat langkah-langkah lain yang lebih detail. Dan seperti dipelajari pada bab sebelumnya. Misalnya. kita bisa dihadapkan pada permasalahan IO (input output). Kita harus memberikan pertanyaan kepada user. input dari user berupa String yang harus diterjemahkan ke dalam tipe data bilangan untuk bisa dikalkulasi. 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. Metode ini disebut penghalusan bertahap (stepwise refinement).

io.out. } x = x + Double. } x = x / 5. Jangan lupa bahwa program tersebut membutuhkan paket java.in)).io. Untuk itu kita harus tambahkan perintah untuk menginisialisasi a dan x dengan 0. try { strbilangan = br. 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. tetapi juga perulangannya menjadi tak menentu. bukan saja hasil rata-ratanya menjadi tak tentu.out. sehingga kita harus menambah import java. perlu diperhatikan bahwa variabel a dan x tidak diketahui nilai awalnya oleh komputer.*. yaitu double x = 0.println("Kesalahan IO. BufferedReader br = new BufferedReader(new InputStreamReader(System. while (a < 5) { System.println("Rata-rata bilangan yang dimasukkan adalah " + x).readLine(). .print("Masukkan bilangan ke-" + a + " : ").parseDouble(strbilangan). a = a + 1. Bayangkan jika nilai a dan x ditentukan oleh komputer secara acak.* di awal kelas.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.out.exit(1). program berhenti"). int a = 0. String strbilangan = null. } catch (IOException ioe) { System. System. System.

googlecode. String strbilangan = null. System.*. } catch (IOException ioe) { System.in)). } x = x / 5.println("Rata-rata bilangan yang dimasukkan adalah } " + x).println("Kesalahan IO. a = a + 1. while (a < 5) { System. System. public class HitungRataRata5Bil { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub double x = 0. 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.out. } Untuk menguji program tersebut. int a = 0.com/svn/trunk/HitungRataRata5Bil package hitungratarata5bil.out.readLine(). try { strbilangan = br.exit(1). BufferedReader br = new BufferedReader(new InputStreamReader(System.parseDouble(strbilangan). .print("Masukkan bilangan ke-" + a + " : ").io. jalankan "Run -> Run" atau Ctrl-F11.out. } x = x + Double. import java. program berhenti").

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

perintah kedua juga merupakan perulangan dari 1 hingga 12.3..2..println("").... } System..12 cetak perkalian i dengan 1.out..12 cetak i*j cetak baris baru Kita bisa terjemahkan ke dalam bahasa Java sebagai for (int i = 1.12 untuk setiap kolom j = 1.12 cetak baris baru Kalau kita jabarkan lebih lanjut.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. i++) { for (int j = 1. i <= 12.3.out..3.2..3. .. sehingga algoritma di atas bisa kita tulis sebagai untuk setiap baris i = 1.print(i*j + " "). j <= 12.2. j++) { System.2.

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

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

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

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

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

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

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

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

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

dan 2 berarti Kelingking. J. telunjuk. .out.println("J untuk Jempol"). Hasil perhitungan komputer dan hasil input dari user akan dibandingkan.Kita akan membuat program untuk main suit. dan Kelingking menang lawan Jempol. Komputer akan menggunakan perintah random() untuk menghitung salah satu dari 3 pilihan. 0 berarti Jempol. T untuk Telunjuk dan K untuk Kelingking. dan K akan diubah menjadi angka 0. Permainan ini terdiri dari dua pemain. Kemudian dengan pernyataan switch.out.println("Masukkan salah satu dari 3 kemungkinan :").println("=============="). kemudian hasilnya siapa yang menang akan ditampilkan di layar. Dalam program ini. Telunjuk menang lawan Kelingking. package mainsuit. Peraturannya : Jempol menang lawan Telunjuk. import java. sedangkan user adalah pemain kedua.out.*.io. dan kelingking. System.println("Permainan suit"). 1 berarti Telunjuk. T.out. System. biasanya dua pemain mengadu suit dengan saling menunjukkan jari. 1. 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 seperti pada komputer. Dalam permainan real. komputer adalah pemain pertama. System. Hanya 3 jari yang boleh dipakai: jempol. User akan diberikan pertanyaan untuk memasukkan J untuk Jempol.

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

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

yaitu 0. maka kita harus ubah menjadi // salah satu suit yang valid. break. 1.out.// 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.println("Suit komputer = Jempol"). // suatu saat "mungkin" nilai random bernilai 3 // karena 3 tidak ada dalam suit kita.random()*3). atau 2 // dalam hal ini kita ganti jadi 2 if (suitKomputer == 3) { suitKomputer = 2.0232323 menjadi 1 suitKomputer = (int)(Math.out. // jika user Telunjuk case 1: .println("Seri"). switch (suitUser) { // jika user Jempol case 0: System.

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

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

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

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

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

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

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

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

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

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. mengambil input dari user dan mengubah input dari user menjadi bilangan real (tipe data double). dan "String pertanyaan" adalah parameternya yaitu berupa pertanyaan yang diberikan kepada user pada saat data akan diambil.. } "public" dan "static" adalah sifat subrutin ini. Kita bisa definisikan subrutin ini dengan public static double ambilDouble(String pertanyaan) { .Kemudian buat kelas baru yang dinamakan KonsolInput. . "double" merupakan tipe data keluarannya karena kita ingin subrutin ini mengembalikan input bertipe double sehingga siap untuk digunakan. "File -> New -> Class".

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

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

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

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

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

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

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

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

maka kita harus ubah menjadi // salah satu suit yang valid.suitUser.random() menghasilkan nilai acak antara 0 dan 1 // jika kita kali 3.break. // suatu saat "mungkin" nilai random bernilai 3 // karena 3 tidak ada dalam suit kita. switch (delta) { case 0: .0232323 menjadi 1 suitKomputer = (int)(Math. 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. atau 2 // dalam hal ini kita ganti jadi 2 if (suitKomputer == 3) { suitKomputer = 2. yaitu 0. } // menghitung siapa yang menang int delta = suitKomputer .random()*3). 1. } } } // sekarang menghitung suit komputer // Math.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

} // 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.

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

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

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

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

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

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

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

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

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

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

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

seperti IllegalArgumentException atau IOException.Penanganan pengecualian menjadi wajib untuk kelas yang bukan kelas turunan dari Error atau RuntimeException. 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. Pengecualian adalah pendekatan yang terstruktur dan terorganisir untuk membuat program tangguh. Misalnya. 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. Pengecualian yang wajib biasanya merupakan kondisi yang berada di luar jangkauan programmer. program akan dipenuhi dengan pernyataan if untuk menguji berbagai macam kondisi kesalahan. 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. Kelas baru tersebut harus diturunkan dari kelas standar Throwable atau kelas turunannya. Bagian berikutnya akan membahas tentang contohcontoh input/output dan penanganan pengecualian dengan lebih gamblang. input ilegal atau aksi ilegal oleh user. Desain Java tidak memungkinkan programmer untuk mengabaikan kondisi tersebut. Pemrograman dengan Pengecualian Pengecualian bisa digunakan untuk membantu kita menulis program tangguh. Untuk membuat kelas pengecualian baru yang mewajibkan penanganan kesalahan. Secara umum. Akan tetapi. Tanpa pengecualian. Dengan pengecualian. di mana kasus-kasus pengecualian akan ditangani di bagian lain. programmer dapat membuat turunan dari kelas Exception atau salah satu kelas turunannya. program akan melempar pegecualian. programmer bisa membuat kelas pengecualian baru. Dalam beberapa kasus. yaitu di dalam klausa catch. Program tangguh harus bisa menangani kondisi seperti ini. Di antara pengecualian yang mewajibkan penanganan pengecualian adalah yang berhubungan dengan rutin input/output. jika tidak ada kelas standar yang cukup mewakili jenis pengecualian tersebut. mungkin akan lebih mudah apabila pengecualian yang dilemparkan merupakan objek dari salah satu kelas pengecualian bawaah Java. kita bisa menulis program yang algoritma yang lebih jelas. Membuat objek dari KesalahanBaca yang berisi // pesan kesalahan super(pesan).

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

itemTerurut++) { .length. // Pindahkan lokasi item dari posisi lok ke lok+1 lok = lok . Setiap penyisipan bisa dilakukan dengan rutin sisip() di atas. 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]. static void urutPenyisipan(int[] A) { // Mengurutkan array A dalam urutan menaik (dari kecil ke besar) int itemTerurut. kemudian memasukkannya kembali satu demi satu. } // Pindah ke lokasi sebelumnya A[lok + 1] = itemBaru. kita tidak benar-benar mengambil semua item dari 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. Dalam algoritma sesungguhnya. // Mulai dari akhir array /* Pindahkan item yang lebih besar dari itemBaru satu posisi. int lok = jmlItem . // Jumlah item yang sudah diurut for (itemTerurut = 1. sambil menjaga agar array tetap terurut selama kita menambah item ke array baru.1. kita hanya cukup mengingat bagian mana yang sudah diurutkan.1.// // dalam array. variabel yang mencatat jumlah item dalam array harus ditambah satu setelah memanggil subrutin ini. itemTerurut < A.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

} // 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 . System. // Jumlah item dalam tumpukan berkurang 1 . jadi buat array yang lebih besar dan // kopi isi tumpukan sekarang ke dalam array baru int[] arrayBary = new int[ 2*item.length) { // Array sudah penuh. item. 0.length).arraycopy(item. arrayBary.1] // Item teratas di dalam tumpukan atas--.public class TumpukanInt { private int[] item = new int[10].length ]. item = arrayBaru. 0. // Menyimpan item dalam tumpukan private int atas = 0. // Banyaknya item dalam tumpukan public void dorong( int N ) { // Tambahkan N ke dalam tumpukan if (atas == item. // Letakkan N di tempat kosong berikutnya atas++. } item[atas] = N.

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

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

isi variabel ini didorong ke dalam tumpukan. misalnya "-x" hanya membutuhkan satu nilai. Algoritma ini bisa diperluas untuk menangani variabel dan konstanta. . Algoritma ini juga bisa dikembangkan untuk operator yang membutuhkan kurang atau lebih dari dua operator. yang menggunakan tumpukan untuk melakukan perhitungan yang telah kita diskusikan. dalam ekspresi "2 3 + *". Ketika variabel ditemukan di dalam ekspresi. karena pada saat itu tumpukan sudah kosong. Ini akan dideteksi oleh algoritma ketika mencoba mengambil nilai kedua dari dalam tumpukan. Kesalahan lain bisa juga muncul ketika menghitung ekspresi "2 3 4 +". Banyaknya nilai yang diambil dari dalam tumpukan bisa disesuaikan dengan berapa banyak nilai yang dibutuhkan. tidak cukup nilai untuk menghitung operasi "*".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. Misalnya. mesin virtual Java adalah "mesin tumpukan". Misalnya. Ekspresi postfix sering digunakan secara internal oleh komputer. Dan sebenarnya. di mana tidak cukup operator untuk menghitung semua nilai. operator "-" sebagai operator negasi. Ini akan dideteksi ketika 2 masih ada di dalam tumpukan di akhir algoritma.

Antrian memiliki dua ujung. Customer akan dilayani dalam urutan ketika mereka datang. Antrian bisa menampung item dengan jenis apa saja. dan selalu dikeluarkan dari depan antrian.Antrian Antrian (queue) adalah struktur data mirip dengan tumpukan. Operasi memasukkan dan mengeluarkan item dari dalam antrian disebut "masuk" dan "keluar" (dalam bahasa Inggris disebut enqueue dan dequeue). Untuk antrian int. Item selalu dimasukkan dari belakang antrian. Suatu item yang ditambahkan di belakang antrian tidak bisa dihapus sebelum item di depannya dihapus. operasi masuk dan keluar dapat diimplementasikan sebagai metode instansi dalam kelas "AntrianInt". Mirip seperti antrian pada kasir atau pada customer service di bank misalnya. yang disebut ujung depan dan ujung belakang. yaitu terdiri dari item dalam urutan tertentu. 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() .

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

kita hampir pasti akan menggunakan kelas turunannya yang mampu menangani operasi yang lebih kompleks. Dalam prakteknya kita akan menggunakan kelas turunan dari kelas-kelas dasar ini.Tapi. Atau dengan kata lain misalnya kita bisa menggunakan PrintWriter untuk menulis file atau mengirim data pada jaringan. PrintWriter adalah kelas turunan dari Writer yang memiliki metode tambahan untuk menulis tipe data Java dalam karakter yang bisa dibaca manusial. 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) . Misalnya. dan kita ingin menggunakan metode pada PrintWriter untuk menulis data. Objek pembungkus ini juga berupa aliran. Ketika kita menulis data ke printableBaskomKarakter dengan menggunakan metode pada PrintWriter yang lebih canggih. Contoh jika baskomKarakter bertipe Writer. 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. maka data tersebut akan ditempatkan di tempat yang sama dengan apabila kita menulis langsung pada baskomKarakter. maka kita bisa membuat PrintWriter printableBaskomKarakter = new PrintWriter(baskomKarakter). sehingga kita juga bisa melakukan baca tulis dari objek yang sama dengan tambahan kemampuan dalam objek pembungkusnya. maka kita bisa membungkus objek Writer dalam objek PrintWriter. akan tetapi kelas ini berorientasi karakter (karena digunakan untuk membaca dan menulis data yang bisa dibaca manusia). Artinya kita hanya perlu membuat antar muka yang lebih baik untuk aliran output yang sama. Artinya operasi baca tulis akan mengambil dan menulis nilai char bukan byte. Jika kita memiliki objek bertipe Writer atau turunannya. yaitu read dan write. Kelas Reader dan Writer memiliki operasi dasar yang hampir sama. Untuk lengkapnya.

Bagaimana caranya jika kita ingin membuat data dalam bentuk bahasa mesin? Paket java. Ketika kita menggunakan metode PrintWriter untuk menulis data ke aliran. kelas PrintWriter memiliki metode public boolean checkError() yang akan mengembalikan true jika ada kesalahan yang terjadi ketika menulis ke dalam aliran. . yaitu DataOutputStream yang bisa digunakan untuk menulis suatu data ke dalam aliran dalam format biner.// 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. data tersebut diubah menjadi rangkaian karakter yang bisa dibaca oleh manusia. dan mengeset nilai tertentu di dalam kelas ini jika kesalahan telah terjadi.io memiliki kelas aliran byte. 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. Akan tetapi. Sehingga kita bisa menggunakan metode pada PrintWriter tanpa khawatir harus menangkap pengecualian yang mungkin terjadi. DataOutputStream berhubungan erat dengan OutputStream seperti hubungan antara PrintWriter dan Writer. Akan tetapi.

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

Metde untuk objek I/O adalah readObject() yang tersedia pada ObjectInputStream dan writeObject(Object obj) yang tersedia dalam ObjectOutputStream. Yang perlu kita lakukan adalah menambahkan "implements Serializable" pada definisi kelas. Mengimplementasi konsep "piping". ObjectInputStream dan ObjectOutputStream hanya bekerja untuk objek yang mengimplementasikan interface yang bernama Serializable. Lbih jauh semua variabel instansi pada objek harus bisa diserialisasi. Artinya komponen GUI pun bisa disimpan dan dibaca dari dalam perangkat I/O menggunakan ObjectInputStream dan ObjectOutputStream. 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. Interface ini ada hanya sebagai penanda untuk kompiler supaya kompiler tahu bahwa objek ini digunakan untuk baca tulis ke suatu media. Ingat bahwa readObject() mengembalikan nilai bertipe Object yang artinya harus di-type cast ke tipe sesungguhnya. 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 . atau objek bertipe File atau dalam file FileDescriptor PipedInputStream SequenceInputStream Menghasilkan data yang ditulis oleh PipedOutputStream. Banyak kelas standar Java yang telah dideklarasikan untuk bisa diserialisasi.ObjectInputStream dan ObjectOutputStream adalah kelas yang bisa dibungkus oleh kelas InputStream dan OutputStream lain. karena interface Serializable tidak mempunyai metode apaapa. Keduanya bisa melemparkan IOException. Artinya kita bisa melakukan input dan output objek pada aliran byte apa saja. termasuk semua komponen kelas Swing dan AWT.

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. atau objek bertipe File atau FileDescriptor PipedOutputStream Informasi yang kita kirim di aliran output Objek PipedInputStream ini akan berakhir pada objek bertipe . bahwa kelas dasar InputStream dan OutputStream hanya memiliki metode-metode paling sederhana. 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. Seperti disebutkan sebelumnya. 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. 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. Kelas FilterInputStream sendiri terdiri dari beberapa jenis. 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.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. Semua Opsional untuk memberikan ByteArrayOutputStream data yang kita kirim akan disimpan di besar buffer yang akan memori ini.

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

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

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

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

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

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

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

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

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

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

Karena program harus bisa mengkopi file jenis apapun. . Akan tetapi kita juga bisa membuat program Java untuk melakukannya. dan sistem operasi manapun memiliki perintah atau cara untuk melakukannya. maka kita bisa membuat FileReader untuk melakukannya dengan menggunakan new FileReader(file). dan kita ingin mengambil karakter dari file tersebut. File lagu atau video misalnya berisi deretan byte yang merupakan representasi digital dari lagu atau video tersebut. Mengkopi File Mengkopi suatu file adalah operasi biasa.out. } } } Berikut ini adalah program lengkapnya yang bisa diimport ke dalam Eclipse. Misalnya.println(" " + isiFile[i]). kita tidak bisa menganggap data di dalam file adalah data yang bisa dibaca manusia. 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. jika file adalah variabel bertipe File.System.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

System.System. } } } }.out.out. Akan tetapi.berikut().println(nilai).println(nilai).waktuMulai > 4000) { System. while (true) genap. Bagian kode yang kita ingin lindungi ini disebut bagian kritis (critical section) dan juga bisa dibuat dengan kata kunci synchronized. System.exit(0).start(). bukan keseluruhan metode. } } Bagian Kritis Kadang-kadang kita hanya ingin mencegah beberapa thread untuk mengakses sebagian kode saja di dalam suatu metode.exit(0).currentTimeMillis() . } // Selesaikan program jika sudah melewati 4 detik if (System. kata kunci ini digunakan dengan menyatakan objek mana yang memiliki kunci yang harus dicek sebelum bagian ini dijalankan. 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 } .

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

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

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

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

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

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

. // 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. // mili detik.garpu kirinya adalah garpu kanan ilmuwan sebelumnya .garpu kanannya adalah garpu kanan ilmuwan sebelumnya (DEADLOCK) ilmuwan[i] = new Ilmuwan(kiri. kiri). kanan = new Garpu().exit(0).garpu kanannya adalah garpu kiri ilmuwan pertama Jika tidak (makan berbalik arah) .length . kanan). // Garpu pertama hanya sebagai penanda // yaitu garpu di kiri ilmuwan pertama Garpu pertama = kiri. else ilmuwan[i] = new Ilmuwan(pertama. // 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].garpu kirinya adalah garpu kiri ilmuwan pertama .1) { ilmuwan[i++] = new Ilmuwan(kiri. // ubah ini menjadi false untuk mencegah deadlock final static int WAKTU_TIMEOUT = 10000. // Mula-mula buat 2 garpu Garpu kiri = new Garpu(). } // // // // // // // // if Sekarang buat ilmuwan terakhir Jika kita ingin membuat deadlock (makan menghadap meja) : . Garpu kanan = new Garpu()."). int i = 0. bisa diganti final static boolean DEADLOCK = true. pertama).. // Keluar dari program setelah jeda waktu selesai if (WAKTU_TIMEOUT > 0) new Timeout(WAKTU_TIMEOUT. // Kelas utama public class IlmuwanMakan { final static int JUMLAH_ILMUWAN = 3. } }.} } // akhir kelas Timeout System. jeda). kiri = kanan. "Waktu habis. // bisa diganti final static int WAKTU_FIKIR_MAKS = 10.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Resize SWT.DefaultSelection SWT.Iconify SWT.MouseDoubleClick Mouse di-double click SWT.MouseDown 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) .MouseHover SWT.Deiconify SWT.Jenis event yang terjadi beserta penjelasannya dirangkum dalam tabel berikut ini : Jenis Event SWT.FocusOut SWT.KeyDown SWT.Expand SWT.MouseEnter SWT.KeyUp 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.MouseMove SWT.Paint SWT.MouseUp SWT.Collapse SWT.FocusIn SWT.Selection SWT.Move SWT.Dispose SWT.

events Tabel berikut menggambarkan perbandingan antara event bertipe dan jenis event dari event tanpa tipe.Show SWT.FocusIn SWT.HardKeyDown SWT.Resize DisposeEvent SWT.Verify SWT.MenuDetect SWT. misalnya MouseEvent.Deactivate SWT.Hide SWT.swt.Help SWT.Arm SWT.Dispose FocusEvent SWT.Modify SWT.SWT.Move SWT. Event bertipe mengikuti pola JavaBeans standar. Event Bertipe ArmEvent ControlEvent Jenis Event Tanpa Tipe SWT.DragDetect 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. Artinya event yang dihasilkan merupakan objek bertipe suatu kelas. Kelas-kelas ini terdapat dalam paket org.Arm SWT.Traverse SWT.Activate SWT. bukan hanya bertipe kelas Event yang jenisnya disimpan dalam variabel tertentu.FocusOut .eclipse.

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

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

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

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

FocusIn SWT.Hide SWT.Dispose SWT.MouseDoubleClic k SWT.Deactivate ShellEvent ShallListener (dan ShellAdapter) shellClosed(ShellEvent) shellDeactivated(ShellEvent) .Show SWT.Selection SWT.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.MouseExit SWT.DefaultSelection nt) widgetSelected(SelectionEvent) shellActivated(ShellEvent) SWT.MouseEnter SWT.KeyUp SWT.Help SWT.Move SWT.MouseDown SWT.Modify SWT.Close SWT.FocusOut SWT.Activate SWT.ControlListener ControlEvent (dan ControlAdapter) DisposeEvent DisposeListener FocusEvent HelpEvent KeyEvent controlMoved(ControlEvent) controlResized(ControlEvent) widgetDisposed(DisposeEvent) SWT.Resize SWT.MouseUp SWT.MouseMove SWT.KeyDown SWT.

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

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

pelacakmouse.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.MouseUp MouseEven MouseMoveListen mouseMove(MouseEvent) t er SWT. Anda bisa mengunduh program ini dan mengimportnya pada Eclipse di sini.MouseEnter MouseTrackListen MouseEven er (dan mouseExit(MouseEvent) t MouseTrackAdapt er) SWT. import org.MouseDown mouseUp(MouseEvent) SWT.widgets. package net.MouseMove mouseEnter(MouseEvent) SWT.eclipse.*.lyracc. . import org.eclipse.*.Kelas Event (event bertipe) Interface/Kelas Listener (listener bertipe) Metode (listener bertipe) Jenis event (event tanpa tipe) Penjelasan Mouse dimouseDoubleClick(MouseEv SWT.MouseExit mouseHover(MouseEvent) SWT.swt.MouseHover Mari kita lihat contoh penggunaan mouse event pada program berikut.swt.

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

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

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

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

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

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

(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 :

misalnya "Ini && Itu" akan menghasilkan "Ini & Itu" Traversal Tab Traversal tab didukung pada semua platform. karena setiap platform memiliki cara sendiri bagaimana memindahkan fokus dari satu widget ke widget lain. kita tidak perlu mendefinisikan apa-apa. Nama traversal tab mungkin agak sedikit salah sasaran.TRAVERSE_ESCAPE Penjelasan Traversal yang terjadi ditutupnya suatu kotak dialog. 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. . menekan tombol panah juga memindahkan fokus. Tidak seperti pada mnemonik.Untuk membuat mnemonik pada karakter '&' sendiri. dan sebenarnya termasuk dalam tombol traversal tab juga. gunakan '&&'. isi detail SWT. Misalnya.Traverse keyboard dideteksi Berikut ini adalah isi event ketika event traversal terjadi. Ketika sampai pada widget terakhir. 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. ketika kita menekan tombol <Tab>. Beberapa tombol lain seperti <Esc> digunakan untuk menutup kotak dialog. maka fokus akan diulang dari widget pertama. Pada beberapa platform. Berikut ini adalah daftar event dan listener yang berkaitan dengan traversal. karena sepertinya hanya tombol <Tab> saja yang bisa digunakan untuk memindahkan fokus dari satu widget ke widget lain. maka fokus akan otomatis pindah ke widget berikutnya.

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

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

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

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

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

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

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. Mengembalikan Object yang merupakan data yang bisa kita tambahkan ke dalam widget Jika kita akan menambahkan banyak data ke dalam objek. • • Bit Gaya Shell Metode pada Shell . Data ini tidak akan ditampilkan pada widget. 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. getData() setData(String key. Objek yang memiliki induk yang berupa shell lain disebut shell sekunder atau shell dialog. 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.Metode dispose() isDisposed() setData(Object o) Penjelasan Menghapus widget dari memori. Data ini disebut data aplikasi. Data ini tidak akan ditampilkan pada widget.

• Event pada Shell Bit Gaya Shell .