Mengenal Bahasa Pemrograman Java

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

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

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

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

Menjalankan Eclipse untuk pertama kali
Menjalankan Eclipse untuk pertama kali

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

• •

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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.

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

Jika Anda ingat.com/svn/trunk/RataRata2 Contoh Program Subrutin dan Variabel Statik Mari kita lihat kembali dan kita akan ubah program MainSuit pada halaman ini.ambilDouble("Masukkan bilangan pertama : "). kita panggil subrutin ambilDouble() dengan perintah bilangan = KonsolInput. Cara lain untuk menentukan pemenangnya adalah dengan mengurangi suitKomputer dan suitUser . dan bilangan = KonsolInput. Dalam program sebelumnya.} } 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. di mana parameternya adalah pertanyaan yang diberikan kepada user sebelum memasukkan data. Telunjuk dilambangkan dengan 1. Pertama-tama kita akan ubah algoritma untuk menentukan siapa yang menang. dan Kelingking dilambangkan dengan 2. kita hapus perintah-perintah untuk mengambil input dari user karena sudah kita implementasikan pada subrutin ambilDouble() di kelas KonsolInput. Jempol dilambangkan dengan 0.googlecode. Pertama. Di kelas RataRata2. kita gunakan pernyataan switch case. yaitu kita tuliskan semua kemungkinan dalam permainan.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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. // Angka pada dadu kedua public PasanganDadu(int nilai1. Java akan membuat konstruktor bawaan apabila tidak ada . mengambil nilai1 dan nilai2 sebagai nilai awal untuk dadu1 dan dadu2 dadu1 = nilai1. } public void kocok() { // Kocok dadu dengan menggunakan bilangan acak antara 1 dan 6 dadu1 = (int)(Math. kelas PasanganDadu di atas kita ubah sehingga kita bisa memberi nilai awal sendiri. int nilai2) { // Konstruktor. int nilai2) . dadu2 = nilai2.random()*6) + 1.. yaitu nilai1 dan nilai2. PasanganDadu dadu = new PasanganDadu(1. class PasanganDadu { public int dadu1. dadu2 = (int)(Math. Konstruktor ini memiliki 2 parameter yang harus diisi ketika konstruktor dipanggil. Ini adalah cara Java mengenal suatu konstruktor dan membedakannya dengan subrutin biasa.". tanpa tipe keluaran dan dengan nama yang sama dengan nama kelas.. Misalnya. Dalam hal ini kita buat konstruktor yang menerima 2 nilai sebagai nilai awal dadu. Misalnya.2). kita tidak bisa lagi membuat objek dengan perintah "new PasanganDadu()". // Angka pada dadu pertama public int dadu2. } } // akhir kelas PasanganDadu Konstruktor dideklarasikan dalam bentuk "public PasanganDadu(int nilai1. Karena sekarang kita telah membuat konstruktor. Membuat objek baru yang variabel intansinya dadu1 dan dadu2 bernilai 1 dan 2.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. } .random() * 6) + 1. dadu2 = (int) (Math. Akan tetapi. // Angka pada dadu kedua public PasanganDadu() { // Isi dadu1 dan dadu2 dengan bilangan acak. // Angka pada dadu pertama public int dadu2.random() * 6) + 1. Sekarang kita akan modifikasi lagi kelas tersebut dengan 2 konstruktor. int nilai2) { // Konstruktor. kita bisa membuat konstruktor lain di kelas tersebut.satupun konstruktor yang didefinisikan. yang mana apabila tidak ada parameter yang diberikan. dengan memanggil metode // kocok() kocok(). karena suatu kelas bisa terdiri dari beberapa konstruktor asalkan parameternya berbeda. } public PasanganDadu(int nilai1. mengambil nilai1 dan nilai2 sebagai nilai awal untuk // dadu1 dan dadu2 dadu1 = nilai1. class PasanganDadu { public int dadu1. maka objek tersebut akan mengisi nilai dadu1 dan dadu2 dengan bilangan acak. dadu2 = nilai2.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

noTelp = noTelp. 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. (Contoh ini adalah contoh dari "array setengah penuh" yang dibahas pada bagian sebelumnya. idks < jmlEntri. jmlEntri++. } String getNoTelp(String nama) { // Ambil nomor telepon dari nama ini atau // kembalikan null jika tidak ada nama ini // di dalam array.nama )) // Nama ketemu! return info[idks]. info[jmlEntri].equals( info[idks]. for (int idks = 0. info[jmlEntri].nama = nama. // Jumlah entri aktual di dalam array void tambahEntri(String nama. . } return null. // Tempat untuk 100 entri int jmlEntri = 0.) Direktori telepon mungkin berupa objek di dalam kelas class DirektoriTelepon { EntriTelepon[] info = new EntriTelepon[100]. idks++) { if (nama. String noTelp) { // Tambah entri baru di akhir array info[jmlEntri] = new EntriTelepon().noTelp. // Nama tidak ketemu.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

sehingga implementasinya menjadi : static boolean pohonBerisiNR( SimpulPohon akar. // Pointer untuk menelusuri pohon pointer = akar. Kita bisa menggunakan perulangan while.item) < 0 ) { // Mulai di akar simpul . String item ) { // Kembalikan true jika item ada di dalam pohon biner. } else if ( item.kanan.compareTo(pointer.equals(pointer. } } // akhir pohonBerisi() Ketika subrutin ini dipanggil. maka // mungkin ada di cabang kanan pohon. } else if ( item. Kembalikan hasil // pencarian di cabang kanan pohon return pohonBerisi( simpul. while (true) { if (pointer == null) { // Kita sudah sampai pada akhir pohon.else { // Jika item sama atau lebih besar dari simpul. parameter pertama adalah variabel anggota statik akar yang menunjuk pada akar seluruh pohonh pencarian biner. SimpulPohon pointer. item ). 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. Perlu dicatat bahwa rekursi bukan sesuatu yang penting dalam mengimplementasikan subrutin ini.item) ) { // Kita sudah menemukan item return true.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

kemudian OK untuk setiap pertanyaan yang mungkin muncul berikutnya.• 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. gunakan Windows Explorer untuk mencari di mana file JAR hasilnya berada. . Sekarang.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

• Event pada Shell Bit Gaya Shell .

Sign up to vote on this title
UsefulNot useful