Mengenal Bahasa Pemrograman Java

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

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

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

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

Menjalankan Eclipse untuk pertama kali
Menjalankan Eclipse untuk pertama kali

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

• •

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// mengisi nilai variabel instansi

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

while (tinggi > rendah) {

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

if (tinggi == rendah) break;

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

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

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

if (tinggi == rendah) break;

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

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

} // akhir while

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

A[rendah] = pivot; return rendah;

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

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

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

Mengaitkan Objek Tumpukan Antrian Pohon Biner Pohon Pengurutan Biner

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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. yaitu ketika iterator sampai pada akhir list.hasNext() bernilai // false. sehingga list masih dalam keadaan terurut menaik ListIterator iter = list.add(itemBaru). if (itemBaru. while (iter.hasNext()) { Object item = iter. maka // perulangan while akan berhenti ketika iter.next(). . } } iter.previous(). break. iter.listIterator(). // Pindahkan iterator sehingga menunjuk pada posisi yang tepat // Jika itemBaru lebih besar dari semua item di dalam list. // dan pada akhir perulangan.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

• Untuk menjalankan program Anda. klik tombol Run seperti pada gambar berikut. • • • • 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.

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

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

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

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

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

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

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

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

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

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

DefaultSelection SWT.Collapse SWT.Expand SWT.KeyDown SWT.Paint SWT.Resize SWT.MouseDown SWT.Deiconify SWT.MouseUp SWT.Selection SWT.MouseExit Penjelasan Tombol ditekan Tombol dilepaskan Tombol mouse ditekan Tombol mouse dilepaskan Mouse berpindah posisi Mouse masuk ke wilayah klien Mouse berada di sekitar klien Mouse keluar dari wilayah klien SWT.Jenis event yang terjadi beserta penjelasannya dirangkum dalam tabel berikut ini : Jenis Event SWT.MouseHover SWT.Dispose SWT.MouseMove SWT.Move SWT.FocusOut SWT.FocusIn 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) .MouseEnter SWT.KeyUp SWT.MouseDoubleClick Mouse di-double click SWT.Iconify SWT.

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

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

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

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

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

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

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

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

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

break. .MouseUp: output = "UP". Shell shell = new Shell(display). // Kelas Listener baru.MouseMove: output = "MOVE". case SWT. case SWT. break. break.type) { case SWT. break. break.public class PelacakMouse { /** * @param args */ public static void main(String[] args) { // Membuat display dan shell baru Display display = new Display().MouseEnter: output="ENTER". switch (e. case SWT. case SWT.MouseExit: output = "EXIT". 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". break. case SWT.MouseDown: output = "DOWN".

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

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

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

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

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

(event bertipe)

Listener (listener bertipe)

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

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

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

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

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

Metode (listener bertipe)

keyPressed(KeyEvent) KeyEvent KeyListener (dan KeyAdapter)

SWT.KeyDown

keyReleased(keyEvent) SWT.KeyUp

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

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

SWT.TAB

Tombol Tab

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

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

SWT.END SWT.INSERT

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

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

SWT.F7

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

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

SWT.F9

SWT.F10 SWT.PAGE_UP

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

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

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

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

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

public class PenghalangTombol {

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

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

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

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

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

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

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

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

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

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

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

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

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

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

• Event pada Shell Bit Gaya Shell .

Sign up to vote on this title
UsefulNot useful