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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

0. arrayBary. } item[atas] = N. item = arrayBaru. 0.length) { // Array sudah penuh. // Banyaknya item dalam tumpukan public void dorong( int N ) { // Tambahkan N ke dalam tumpukan if (atas == item.public class TumpukanInt { private int[] item = new int[10].arraycopy(item.length). } // 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 .length ].1] // Item teratas di dalam tumpukan atas--. // 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. // Menyimpan item dalam tumpukan private int atas = 0. System. // Letakkan N di tempat kosong berikutnya atas++. item.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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. Kelas PrintWriter menangkap pengecualian IOException secara internal. Akan tetapi. 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. . Bagaimana caranya jika kita ingin membuat data dalam bentuk bahasa mesin? Paket java. data tersebut diubah menjadi rangkaian karakter yang bisa dibaca oleh manusia.io memiliki kelas aliran byte. DataOutputStream berhubungan erat dengan OutputStream seperti hubungan antara PrintWriter dan Writer. dan mengeset nilai tertentu di dalam kelas ini jika kesalahan telah terjadi. 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.

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

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

akan tetapi tidak mengubah bagaimana I/O itu sendiri bekerja. Semua Opsional untuk memberikan ByteArrayOutputStream data yang kita kirim akan disimpan di besar buffer yang akan memori ini. Kelas-kelas ini memperbanyak metode baca/tulis untuk kemudahan pemrograman. disiapkan String yang berupa nama FileOutputStream Untuk menulis informasi ke dalam file suatu file.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. Kenapa dekorator? Karena kelas-kelas ini hanya memberikan fungsionalitas tambahan. Atau dengan kata menentukan besar lain "gunakan buffer" untuk baca tulis buffer sendiri Mencatat nomor baris dalam InputStream. Kelas FilterInputStream sendiri terdiri dari beberapa jenis. atau objek bertipe File atau FileDescriptor PipedOutputStream Informasi yang kita kirim di aliran output Objek PipedInputStream ini akan berakhir pada objek bertipe . 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. 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. bahwa kelas dasar InputStream dan OutputStream hanya memiliki metode-metode paling sederhana. 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. Seperti disebutkan sebelumnya.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

try { Thread.println(Thread. nama).sleep(10). } } } }. } } // akhir KelasRunnableAnonim // Menjalankan thread dari dalam metode dan kelas anonim class ThreadViaMetode { private int hitungMundur = 5.currentThread(). private String nama. } } // akhir KelasRunnableBernama // Kelas dalam implementasi runnable anonim class KelasRunnableAnonim { private int hitungMundur = 5. if (--hitungMundur == 0) return. } public void runThread() { if (t == null) { // Definisi kelas anonim dari dalam metode t = new Thread(nama) { public void run() { while (true) { System. public KelasRunnableAnonim(String nama) { t = new Thread(new Runnable() { public void run() { while (true) { System.nama = nama. private Thread t.start(). } catch (InterruptedException e) { throw new RuntimeException(e).println(getName() + " : " + hitungMundur).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).out. if (--hitungMundur == 0) return.getName() + " : " + hitungMundur). // akhir kelas dalam anonim t. private Thread t. .

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

• Klik Finish. 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. gunakan Windows Explorer untuk mencari di mana file JAR hasilnya berada. Sekarang.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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. akan lebih mudah jika kita menandai data tersebut dengan suatu kunci key. Mengembalikan true jika widget ini sudah dihapus dari memori Menambahkan data tambahan (terserah kita) ke dalam suatu widget. Objek yang memiliki induk yang berupa shell lain disebut shell sekunder atau shell dialog. Data ini tidak akan ditampilkan pada widget. • • Bit Gaya Shell Metode pada Shell .Metode dispose() isDisposed() setData(Object o) Penjelasan Menghapus widget dari memori. Mengembalikan Object yang merupakan data tambahan ke suatu widget.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. getData() setData(String key. Mengembalikan Object yang merupakan data yang bisa kita tambahkan ke dalam widget Jika kita akan menambahkan banyak data ke dalam objek. yang memiliki kunci key Mengembalikan int yang merupakan bit gaya suatu widget. Objek yang tidak memiliki induk (atau induknya bertipe Display) disebut shell tingkat paling tinggi. Data ini tidak akan ditampilkan pada widget. Data ini disebut data aplikasi.

• Event pada Shell Bit Gaya Shell .

Sign up to vote on this title
UsefulNot useful