P. 1
Belajar JAVA With Eclipse

Belajar JAVA With Eclipse

|Views: 3,194|Likes:

More info:

Published by: Febri Ardinarr Estrada on Jul 24, 2011
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less

06/01/2014

pdf

text

original

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

kondisi_variabel harus berbentuk pernyataan boolean seperti suatu_kondisi pada pernyataan while. kondisi_variabel. yaitu instruksi mengubah nilai kondisi variabel untuk membatasi perulangan sehingga akan selesai suatu saat. tidak berulang terus menerus. dalam bentuk variabel = nilai_awal. dan terakhir update_variabel. update_variabel) { banyak_perintah } Di sini inisialisasi variabel bisa berupa apa saja yang berbentuk perintah. variabel <= nilai_maksimum. yang artinya perulangan akan terus dieksekusi tanpa henti. dapat dituliskan juga dalam bentuk for (inisialisasi_variabel. Biasanya perulangan ini memiliki bentuk seperti for (variabel = nilai_minimum. inisialisasi_variabel. kondisi_variabel. yaitu memberikan nilai awal suatu variabel. Bagian yang tidak diisi yang selalu digantikan dengan true. diakhiri dengan nilai_maksimum dengan jeda 1. misalnya memberikan variabel dengan nilai awal tertentu.perintah update_variabel } Di sini perulangan while memiliki 3 komponen penting. Untuk menghentikannya. Bentuk paling umum dari perulangan for adalah menghitung. yaitu inisialisasi. Sedangkan update_variabel juga berbentuk perintah. Pada perulangan for. yaitu pengujian bahwa perulangan akan terus dilakukan selama kondisi ini bernilai true. variabel++) { perintah } Perhatikan bagian terakhir adalah menaikkan nilai variabel dengan 1. perintah break harus diberikan ditengah-tengah badan perulangan. . yang artinya perulangan akan dimulai dengan nilai_minimum. atau update_variabel dapat dikosongkan dan tidak harus selalu diisi. suatu_kondisi_variabel. ketiga komponen ini dirangkai menjadi satu dalam bentuk for (inisialisasi_variabel. kondisi_variabel. 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 . j--) { System.out. kita bisa ekspresikan dengan for (i = 1.println(i).17. i <= 10. atau dengan kata lain.Contoh. misalnya i dari 1 hingga 10 dan j dari 10 hingga 1.println(i + " " + j). Untuk banyak kasus.out. } Atau jika kita ingin menghitung maju dan mundur pada saat yang bersamaan. i++) { System. Java adalah bahasa pemrograman ketat. } Catatan penting! Variabel yang akan digunakan. mulai dari 2 hingga 17 dengan jeda 3. jika kita ingin berhitung 2.out. i--) { System. adalah variabel yang harus dideklarasikan sebelumnya. j = 10.println(i). yang merupakan deklarasi variabel i dengan tipe data int sekaligus menginisialisasi nilainya dengan 1.14. i += 3) { System. i <= 10. kita bisa mengekspresikan for dengan for (i = 2. deklarasi variabel dan perulangannya bisa dilakukan serentak pada bagian inisialisasi variabel.11. Perulangan for bertingkat Seperti pada perulangan while. yang artinya semua harus didefinisikan dengan jelas sebelum digunakan. artinya perulangan for di dalam perulangan for. kita bisa menggunakan perintah seperti for (i = 20.8. perulangan for pun dapat dilakukan bertingkat. i >= 0.5. dalam contoh di atas i dan j.out.println(i) } Perhatikan ada imbuhan int di depan inisialisasi variabel i. i <= 17. } Untuk menghitung mundur. Misalnya for (int i = 1. i++.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Ingatkah bahwa subrutin main() yang biasa kita gunakan dalam contoh-contoh program memiliki bentuk seperti berikut ? public static main(String[] args) { . Sifat "public" dan "private" dinamakan penentu akses (access specifier). "boolean" adalah tipe_keluaran // "kurangDari" adalah nama subrutin // parameternya ada 2.. double y) { // "static" adalah sifat. } ... // perintah untuk memainkan game ditulis di bagian ini } int ambilNdata(int N) { // tidak ada sifat. Subrutin pertama memiliki sifat "public" yang artinya subrutin ini dapat dipanggil dari bagian manapun. // perintah untuk mengambil N data ditulis di bagian ini } static boolean kurangDari(double x.. 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". 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 ... termasuk dari luar kelas yang dimaksud. maka otomatis subrutin itu memiliki sifat "package" yang artinya hanya bisa dipanggil dari paket yang sama dari kelas di mana ia didefinisikan. dan subrutin ini tidak dibahas dalam bagian ini..... Jika tidak disebutkan jenis aksesnya dalam suatu definisi subrutin. "int" adalah tipe_keluaran // "ambilNdata" adalah nama subrutin // dan parameternya adalah N yang memiliki tipe data int .

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

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

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

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

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

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

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

Pertama-tama kita akan ubah algoritma untuk menentukan siapa yang menang. dan Kelingking dilambangkan dengan 2.ambilDouble("Masukkan bilangan pertama : ").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 berikutnya (atau 0 untuk mengakhiri) : "). Pertama. Telunjuk dilambangkan dengan 1. Dalam program sebelumnya. Jempol dilambangkan dengan 0. kita hapus perintah-perintah untuk mengambil input dari user karena sudah kita implementasikan pada subrutin ambilDouble() di kelas KonsolInput. Jika Anda ingat. Di kelas RataRata2. kita panggil subrutin ambilDouble() dengan perintah bilangan = KonsolInput.} } Perhatikan beberapa perubahan di dalam program ini. 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. kita gunakan pernyataan switch case.googlecode. dan bilangan = KonsolInput. Cara lain untuk menentukan pemenangnya adalah dengan mengurangi suitKomputer dan suitUser . yaitu kita tuliskan semua kemungkinan dalam permainan.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// mengisi nilai variabel instansi

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

while (tinggi > rendah) {

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

if (tinggi == rendah) break;

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

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

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

if (tinggi == rendah) break;

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

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

} // akhir while

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

A[rendah] = pivot; return rendah;

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

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

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

Mengaitkan Objek Tumpukan Antrian Pohon Biner Pohon Pengurutan Biner

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

println("Files dalam direktori \"" + direktori + "\":").File direktori.println("Kesalahan IO terjadi").println("Tidak ada direktori ini!"). else System.list().out.exists() == false) System.out.out. } else { isiFile = direktori.readLine(). } catch(IOException ioe) { 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.").println("Ini bukan direktori. System.length. System.out. for (int i = 0. i < isiFile. String[] isiFile. } direktori = new File(namaDirektori).exit(1).isDirectory() == false) { if (direktori. i++) . try { namaDirektori = br. System.in)). if (direktori.print("Masukkan nama direktori : ").out.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

"). // 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]. // Kelas utama public class IlmuwanMakan { final static int JUMLAH_ILMUWAN = 3. // ubah ini menjadi false untuk mencegah deadlock final static int WAKTU_TIMEOUT = 10000. int i = 0.. "Waktu habis. // bisa diganti final static int WAKTU_FIKIR_MAKS = 10. bisa diganti final static boolean DEADLOCK = true. // Mula-mula buat 2 garpu Garpu kiri = new Garpu(). else ilmuwan[i] = new Ilmuwan(pertama. kiri = kanan. // mili detik. pertama). kanan). Garpu kanan = new Garpu(). } // // // // // // // // if Sekarang buat ilmuwan terakhir Jika kita ingin membuat deadlock (makan menghadap meja) : . } }. kanan = new Garpu().1) { ilmuwan[i++] = new Ilmuwan(kiri.garpu kirinya adalah garpu kiri ilmuwan pertama . jeda).exit(0). kiri).} } // akhir kelas Timeout System. // Garpu pertama hanya sebagai penanda // yaitu garpu di kiri ilmuwan pertama Garpu pertama = kiri.garpu kanannya adalah garpu kanan ilmuwan sebelumnya (DEADLOCK) ilmuwan[i] = new Ilmuwan(kiri. // Keluar dari program setelah jeda waktu selesai if (WAKTU_TIMEOUT > 0) new Timeout(WAKTU_TIMEOUT.garpu kanannya adalah garpu kiri ilmuwan pertama Jika tidak (makan berbalik arah) .length .garpu kirinya adalah garpu kanan ilmuwan sebelumnya . . // 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-garpu ini akan diambil oleh ilmuwan ketika hendak makan. Setiap kali. karena semua ilmuwan duduk pada posisi melingkar. Padahal sebenarnya tidak demikian. maka ilmuwan tersebut akan menunggu hingga garpu selesai digunakan. dan ilmuwan sebelahnya menunggu garpu sebelahnya lagi. Jika bernilai true maka program cepat atua lambat pasti akan mengalami deadlock. Dan karena posisi duduknya melingkar. Jika nilainya tidak nol. Setiap Ilmuwan diberi referensi ke garpu kiri dan garpu kanan. Mungkin kita beranggapan dengan mengubah waktu berfikir setiap ilmuwan. Sedangkan garpu kanan ilmuwan baru adalah objek garpu baru. Pada versi di mana DEADLOCK bernilai true. garpu kiri dipindah ke garpu kanan. Pada proses yang sulit atau tidak mungkin deadlock (jika variabel DEADLOCK false. Garpu kiri ilmuwan baru adalah garpu kanan ilmuwan sebelumnya. atau waktu fikir ilmuwan sangat panjang). Jika garpu sedang digunakan oleh ilmuwan lain. Mula-mula garpu kiri dahulu yang dicoba untuk diambil. mungkin saja pada suatu waktu semua ilmuwan akan makan dan saling menunggu garpu di sebelahnya. Objek pertama. Setelah digunakan. mereka tidak akan makan secara bersamaan sehingga kemungkinan terjadinya deadlock menjadi lebih kecil. maka proses akan berhenti pada waktu time out. Coba ganti variabelnya dengan beberapa nilai dan amati seberapa cepat deadlock terjadi. atau jumlah ilmuwan banyak. Dalam metode run() serorang ilmuwan makan dan berfikir terus menerus. juga disimpan dalam variabel pertama akan digunakan kemudian. Ada empat konstanta yang bisa kita ubah-ubah di dalam kelas IlmuwanMakan. Deadlock ditandai dengan semua ilmuwan saling menunggu satu sama lain hingga waktu time out berakhir. Di dalam metode makan(). baru kemudian garpu kanan. JUMLAH_ILMUWAN dan WAKTU_FIKIR_MAKS adalah banyaknya ilmuwan yang ada dan waktu fikir ilmuwan seperti dijelaskan sebelumnya. yaitu WAKTU_TIMEOUT digunakan untuk menghentikan semua proses pada waktu tertentu. garpu kanan akan dilepas terlebih dahulu baru kemudian garpu kiri. dua objek Garpu akan dibuat. maka nilai variabel ini akan digunakan sebagai argumen perintah sleep() dalam kelas Ilmuwan. akan tetapi garpu kanannya adalah garpu pertama. seorang ilmuwan akan mengambil garpu dengan melakukan sinkronisasi pada garpu tersebut. Variabel ketiga DEADLOCK berupa boolean yang bisa berisi true atau false. Untuk menghindari deadlock.} } Kelas Garpu dan Ilmuwan menggunakan penghitung otomatis untuk memberi nomor identifikasi tersendiri untuk setiap objek Garpu dan Ilmuwan yang diciptakan. Setelah array objek Ilmuwan dibuat. semua saling menunggu satu sama lain. Setiap objek ilmuwan akan diberi garpu kiri dan kanannya. kecuali objek ilmuwan terakhir. garpu kiri ilmuwan terakhir adalah garpu kanan ilmuwan sebelumnya. seringkali sebelum deadlock terjadi. kita bisa menggantinya dengan false. Dengan pengaturan seperti ini. Bayangkan meja ilmuwan dibuat dalam urutan melingkar berlawanan arah jarum jam. Variabel keempat. . Variabel statik waktuFikirMaks adalah waktu maksimum yang digunakan oleh ilmuwan untuk berfikir. (Seperti pada gambar berikut).

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

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

requestStop().schedule(new TimerTask() { public void run() { System. karena dilakukan dalam 1 clock). 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.out.println("Permintaan berhenti"). threadBaru. Tugas thread ini adalah mencetak 10000 angka. . // run() setelah 500 mili detik } } Variabel stop harus bertipe volatile sehingga metode run() pasti bisa melihat variabel ini (jika tidak. maka nilainya bisa saja di-cache). new Timer(true).start(). threadBaru. 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().stop = true. 500).

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Iconify SWT.Collapse SWT.FocusIn SWT.MouseEnter 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.Selection SWT.MouseHover SWT.Dispose SWT.Resize SWT.Jenis event yang terjadi beserta penjelasannya dirangkum dalam tabel berikut ini : Jenis Event SWT.MouseDown SWT.Deiconify SWT.DefaultSelection SWT.MouseDoubleClick Mouse di-double click SWT.FocusOut SWT.MouseMove SWT.KeyDown SWT.MouseUp SWT.KeyUp SWT.Paint SWT.Move SWT.Close Suatu widget diberi perintah untuk menggambar dirinya Posisi suatu widget berubah Ukuran widget berubah Widget dihapus Suatu aksi pemilihan dilakukan dalam widget (misalnya memilih item pada drop down list Ada pilihan awal pada suatu widget Widget menerima fokus dari keyboard Widget kehilangan fokus dari keyboard Item pada pohon dikembangkan Item pada pohon ditutup Jendela Shell diminimasi Jendela Shell dibuka (restore) Jendela Shell ditutup (dengan tombol X) .Expand SWT.

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

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

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

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

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

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

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

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

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

.MouseExit: output = "EXIT". case SWT. break. break. break.MouseUp: output = "UP".MouseEnter: output="ENTER". case SWT. break. break. switch (e.type) { case SWT. menggunakan listener tanpa tipe Listener mouseListener = new Listener() { // metode handleEvent pada interface Listener harus diimplementasikan public void handleEvent(Event e) { String output = "UNKNOWN".MouseDoubleClick: output = "DOUBLE". // Kelas Listener baru.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).MouseMove: output = "MOVE". case SWT. case SWT.MouseDown: output = "DOWN". break. case SWT.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

• Event pada Shell Bit Gaya Shell .

You're Reading a Free Preview

Download
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->