Thursday, October 5, 2017

KULIAH 3 Java: Array dan String


4. Array dan String




Pada bab ini, Anda akan mulai mempelari bagaimana menggunakan objek-objek Java. Anda lebih dahulu akan belajar array, yang dapat dipakai untuk menangani sejumlah variabel bertipe sama melalui satu nama variabel, dan kemudian Anda akan mempelajari bagaimana menangani string karakter. Di akhir bab ini, Anda akan telah mempelajari:
ð        Apa itu array dan bagaimana Anda mendeklarasikan dan menginisialisasi array
ð        Bagaimana Anda mengakses elemen-elemen array
ð        Bagaimana Anda memanfaatkan elemen-elemen array
ð        Bagaimana mendeklarasikan array yang memuat array-array
ð        Bagaimana menciptakan array yang memuat array-array yang berukuran berbeda
ð        Bagaimana menciptakan objek-objek String
ð        Bagaimana menciptakan dan menggunakan array yang memuat objek-objek String
ð        Apa operasi-operasi yang tersedia bagi objek-objek String
ð        Apa itu objek StringBuffer dan bagaimana relasinya dengan objek String
ð        Apa operasi-operasi yang tersedia bagi objek-objek StringBuffer


Array
Dengan tipe data fundamental Java yang telah Anda lihat pada bab-bab terdahulu, setiap pengenal berkaitan dengan satu variabel tunggal. Tetapi ketika Anda ingin menangani sejumlah nilai bertipe data sama, Anda tentu tidak ingin menamai setiap nilai secara individual. Apa yang Anda butuhkan adalah array.

Array adalah sebuah objek yang merupakan sekumpulan variabel bertipe sama. Setiap variabel pada array dinamakan dengan elemen array. Untuk mengakses elemen tertentu pada sebuah array, Anda menggunakan nama array yang dikombinasikan dengan sebuah nilai integer bertipe int, yang dikenal sebagai indeks. Anda menempatkan indeks diapit kurung-siku yang ada setelah nama array; misalnya, data[99] mengakses elemen pada array data yang berkaitan dengan nilai indeks 99. Elemen pertama array memiliki indeks 0, elemen keduanya memiliki indeks 1, dan seterusnya. Jadi, data[99] mengakses elemen keseratus dari array data. Nilai indeks tidak harus berupa literal integer. Indeks dapat berupa sembarang ekspresi yang menghasilkan nilai bertipe int yang nilainya sama dengan atau lebih besar dari 0.


Variabel Array
Variabel array dan array yang ditunjuk oleh variabel array adalah dua entitas yang berbeda. Memori yang dialokasikan untuk sebuah variabel array menyimpan referensi ke sebuah objek array, bukan array itu sendiri. Objek array itu sendiri merupakan entitas berbeda yang berada di tempat lain pada memori.

Anda tidak diwajibkan menciptakan array saat mendeklarasikan sebuah variabel array. Anda dapat lebih dahulu menciptakan variabel array dan kemudian menggunakannya untuk menyimpan sebuah referensi yang menunjuk ke array tertentu.

Anda dapat mendeklarasikan variabel array integer prima dengan statemen berikut:

int[] prima;  // Mendeklarasikan sebuah variabel array integer

Variabel prima sekarang menjadi penunjuk atau referensi ke sebuah array integer yang belum Anda definisikan. Belum ada memori yang dialokasikan untuk memuat array sejauh ini. Variabel prima hanyalah sebuah lokasi pada memori yang dapat menyimpan sebuah referensi yang menunjuk ke sebuah array. Kurung siku yang ada setelah tipe data pada statemen di atas mengindikasikan bahwa variabel tersebut diperuntukkan untuk mereferensi sebuah variabel yang memuat nilai-nilai int, bukan untuk menyimpan sebuah nilai bertipe int. Tipe data dari variabel array tersebut adalah int[].

Anda juga akan menjumpai sintaksis alternatif dalam mendeklarasikan sebuah variabel array:

int prima[];         // Mendeklarasikan sebuah variabel array integer

Di sini kurung-siku ditempatkan setelah nama variabel, bukan setelah nama tipe data. Ini ekivalen dengan statemen sebelumnya, dan Anda dapat menggunakan salah satu dari dua jenis deklarasi yang ada. Banyak programer lebih memilih menggunakan notasi awal, karena int[] cenderung lebih jelas mengindikasikan bahwa tipe data tersebut merupakan array dengan nilai-nilai bertipe int.


Mendefinisikan Array
Setelah Anda mendeklarasikan sebuah variabel array, Anda kemudian dapat mendefinisikan sebuah array yang akan ditunjuk atau direferensi oleh variabel array tersebut:

prima = new int[10]; // Mendefinisikan sebuah array yang memuat 10 integer

Statemen ini menciptakan sebuah array yang akan menyimpan 10 nilai bertipe int, dan menyimpan sebuah referensi yang menunjuk ke array ke dalam variabel prima. Referensi merupakan alamat memori dimana array berada. Anda dapat pula mendeklarasikan variabel array dan mendefinisikan array bertipe int untuk memuat 10 nilai prima dengan satu statemen, seperti ditunjukkan pada Gambar 4-1.



Gambar 4-1

Bagian pertama dari definisi array menetapkan tipe data array. Tipe data elemen array, pada kasus ini int, diikuti oleh sepasang kurung-siku kosong untuk mengindikasikan bahwa Anda sedang mendeklarasikan sebuah array, bukan sebuah variabel bertipe int. Bagian statemen yang ada setelah tanda sama-dengan mendefinisikan array. Katakunci new mengindikasikan bahwa Anda sedang mengalokasikan memori baru untuk array, dan int[10] menetapkan bahwa dibutuhkan memori untuk 10 variabel bertipe int pada array.

Karena tiap elemen pada array prima adalah sebuah variabel bertipe int yang memerlukan 4 byte, array ini memerlukan memori 40 byte, ditambah dengan 4 byte bagi variabel prima untuk menyimpan referensi ke array (alamat array). Ketika sebuah array diciptakan seperti ini,  semua elemen array secara otomatis diinisialisasi dengan nilai default. Nilai awal default adalah nol untuk kasus array dengan nilai-nilai numerik, nilai default false untuk array dengan nilai-nilai boolean, nilai default ‘\u000’ untuk array dengan nilai-nilai bertipe char, dan nilai default null untuk array dengan nilai-nilai bertipe kelas.

Perhatikan statemen berikut:

double[] arrayKu = new double[100];

Statemen ini merupakan sebuah deklarasi atas variabel array arrayKu. Statemen ini juga mendefinisikan array, karena ukuran array ditentukan. Variabel arrayKu akan mereferensi ke sebuah array yang memuat 100 nilai bertipe double, dan tiap elemen array akan memiliki nilai 0.0 secara default. Karena ada 100 elemen pada array ini, nilai-nilai indeks yang legalnya dimulai dari 0 sampai 99.

Panjang Array
Anda dapat menentukan panjang array, yaitu banyak elemen yang dimuat array, menggunakan length, yang merupakan anggota data dari objek array. Misalnya, untuk arrayKu yang telah Anda definisikan sebelumnya, Anda dapat menentukan panjangnya menggunakan arrayKu.length, yang akan menghasilkan nilai 100. Anda dapat menggunakan anggota length dari sebuah array untuk mengendalikan sebuah loop for numerik yang beriterasi terhadap elemen-elemen array.


Mengakses Elemen Array
Seperti yang disebutkan sebelumnya, Anda bisa mengakses elemen array menggunakan nama array yang diikuti dengan nilai indeks elemen yang diapit di dalam kurung-siku. Anda menetapkan nilai indek menggunakan sembarang ekspresi yang menghasilkan nilai nol atau nilai positif bertipe int. Jika Anda menggunakan sebuah nilai bertipe long sebagai indeks elemen, Anda akan mendapatkan pesan error dari kompilator; jika perhitungan indeks menggunakan variabel-variabel bertipe long dan hasilnya juga bertipe long, maka Anda perlu melakukan konversi tipe eksplisit menjadi tipe int.

Anda mengakses elemen pertama dari array prima yang telah dideklarasikan sebelumnya dengan prima[0], dan Anda mengakses elemen kelima pada array tersebut dengan prima[4]. Nilai indeks maksimum untuk sebuah array adalah banyak elemen array yang dikurangi dengan satu. Java akan memeriksa apakah nilai indeks yang Anda berikan valid atau tidak. Jika Anda menggunakan sebuah nilai indeks yang lebih kecil dari 0, atau lebih besar dari nilai indeks untuk elemen terakhir pada array, maka sebuah eksepsi akan dilemparkan. Pelemparan eksepsi adalah sebuah mekanisme untuk mengindikasikan adanya error, dengan tiap jenis eksepsi menandakan error yang berbeda. Tipe eksekusi untuk kasus ini adalah IndexOutOfBoundsException. Ketika eksepsi semacam itu dilemparkan, program Anda akan berhenti secara normal. Anda akan mempelajari tentang eksepsi pada Bab 7, termasuk di dalamnya tentang bagaimana menangani eksepsi dan menghindari terminasi pada program Anda.

Array prima adalah sebuah contoh dari apa yang dinamakan dengan array satu-dimensi, karena tiap elemen array diakses menggunakan satu indeks, mulai dari 0 sampai 9 pada kasus ini. Anda nanti akan melihat bahwa array juga dapat memiliki dua atau lebih dimensi.

Mendaur-Ulang Variabel Array
Seperti yang telah dijelaskan di awal bab ini, sebuah variabel array terpisah dari array yang direferensinya atau yang ditunjuknya. Anda dapat menggunakan sebuah variabel array untuk menyimpan sebuah referensi dari array-array yang berbeda pada titik-titik berbeda pada program Anda. Dimisalkan bahwa Anda telah mendeklarasikan dan mendefinisikan variabel array prima seperti sebelumnya:

int[] prima = new int[10]; // Mengalokasikan sebuah array dengan 10 elemen integer

Ini akan menghasilkan sebuah array dengan 10 elemen bertipe int. Dimisalkan bahwa di bagian selanjutnya pada program, Anda ingin menggunakan variabel array prima untuk mereferensi ke sebuah array yang lebih besar, katakanlah dengan 50 elemen. Anda bisa melakukannya dengan menuliskan:

prima = new int[50]; // Mengalokasikan sebuah array dengan 50 elemen integer

Sekarang variabel prima mereferensi ke sebuah array baru dengan 50 elemen bertipe int yang terpisah dari array semula. Ketika statemen ini dieksekusi, array sebelumnya dengan 10 elemen akan dibuang, berikut dengan semua nilai data yang disimpan di dalamnya. Variabel prima sekarang dapat dipakai untuk mereferensi array baru. Ini diilustrasikan pada Gambar 4-2.

Gambar 4-2

Setelah statemen di atas dieksekusi seperti ditunjukkan pada Gambar 4-2, variabel array prima sekarang menunjuk atau mereferensi ke sebuah array integer baru yang memiliki 50 elemen dengan nilai-nilai indeks dimulai dari 0 sampai 49. Meskipun Anda dapat mengubah array yang direferensi oleh variabel array, tetapi Anda tidak dapat mengubah tipe data dari nilai yang tersimpan pada elemen array. Semua array yang direferensi oleh variabel array harus memiliki tipe data sama yang telah ditetapkan ketika Anda mendeklarasikan variabel array.

Variabel prima, misalnya, hanya dapat mereferensi array-array bertipe int[]. Array dengan elemen-elemen bertipe int dipakai pada ilustrasi, tetapi aturan yang sama berlaku untuk array-array dengan elemen-elemen bertipe long atau double.


Menginisialisasi Array
Anda dapat menginisialisasi elemen-elemen pada sebuah array dengan nilai-nilai Anda sendiri ketika Anda mendeklarasikannya, dan pada saat yang sama menentukan berapa banyak elemen yang akan dimiliki array. Untuk melakukannya, Anda hanya perlu menambahkan sebuah tanda sama-dengan yang diikuti dengan daftar nilai elemen yang diapit di antara kurung-kurawal. Sebagai contoh, Anda dapat mendefinisikan sekaligus menginisialisasi sebuah array dengan statemen berikut:

int[] prima = {2, 3, 5, 7, 11, 13, 17};  // Sebuah array dengan 7 elemen

Ini akan menciptakan sebuah array prima dengan elemen-elemen yang cukup untuk menyimpan semua nilai awal yang diberikan di dalam kurung-kurawal, pada kasus ini tujuh elemen. Ukuran array ditentukan oleh banyaknya nilai awal. Nilai-nilai yang ditugaskan kepada elemen-elemen array pada contoh ini adalah prima[0] dengan nilai awal 2, prima[1] dengan nilai awal 3, prima[2] dengan nilai awal 5, dan seterusnya.

Jika Anda menetapkan nilai-nilai awal untuk sebuah array, Anda perlu mencantumkan nilai untuk semua elemen. Jika Anda hanya ingin menetapkan nilai untuk sebagian dari elemen array, Anda perlu menggunakan sebuah statemen penugasan untuk tiap elemen array. Sebagai contoh:

int[] prima = new int[100];
prima[0] = 2;
prima[1] = 3;

Statemen pertama mendeklarasikan dan mendefinisikan sebuah array integer dengan 100 elemen, yang semuanya diinisialisasi nol secara default. Dua statemen penugasan kemudian menetapkan nilai untuk dua elemen pertama pada array.

Anda juga dapat menginisialisasi elemen-elemen pada sebuah array menggunakan loop for untuk beriterasi atas semua elemen dan menetapkan nilai untuk tiap elemen array:

double[] data = new double[50];   // Sebuah array dengan 50 elemen bertipe double
for(int i = 0; i < data.length; i++) {   // i dari 0 sampai data.length-1
   data[i] = 1.0;
}

Untuk sebuah array dengan length elemen, nilai-nilai indeks untuk elemen-elemennya dimulai dari 0 sampai length-1. Statemen kendali loop for dituliskan sehingga variabel loop i dimulai dari 0 dan diinkremen sebesar 1 pada tiap iterasi sampai data.length-1. Ketika i diinkremen sampai data.length, loop akan berakhir. Jadi, loop ini menetapkan nilai awal 1 bagi tiap elemen array. Penggunaan loop for dengan cara ini adalah salah satu mekanisme standar untuk memberikan nilai awal bagi tiap elemen array. Anda nanti akan melihat bahwa Anda dapat menggunakan loop for berbasis koleksi untuk beriterasi dan mengakses elemen-elemen array.


Menggunakan Metode Utilitas Untuk Menginisialisasi Array
Anda dapat pula menggunakan sebuah metode yang didefinisikan pada kelas Arrays dalam paket java.util untuk menginisialisasi sebuah array. Sebagai contoh, untuk menginisialisasi array data yang didefinisikan pada fragmen kode sebelumnya, Anda dapat menggunakan statemen berikut:

Arrays.fill(data, 1.0);    // Mengisi semua elemen dari array data dengan nilai 1.0

Argumen pertama dari metode fill() adalah nama array yang akan diisi. Argumen kedua adalah nilai yang akan dipakai untuk menetapkan nilai bagi semua elemen. Metode ini dapat dipakai untuk semua array dengan tipe data primitif. Tentu, agar statemen ini dapat dikompilasi dengan benar, Anda memerlukan sebuah statemen import di awal file sumber.

import java.util.Arrays;

Statemen ini mengimpor nama kelas Arrays ke dalam file sumber sehingga Anda dapat menggunakan metode pada program tanpa perlu menyebutkan nama kelas. Tanpa statemen import, Anda masih dapat mengakses kelas Arrays menggunakan nama utuh. Pada kasus ini, statemen untuk menginisialisasi array dapat dituliskan:

java.util.Arrays.fill(data, 1.0); // Mengisi semua elemen array data dengan nilai 1.0

Tentu, karena fill() adalah sebuah metode statik pada kelas Arrays, Anda dapat mengimpor nama metode ke dalam file sumber Anda:

import static java.util.Arrays.fill;

Sekarang Anda dapat memanggil metode tanpa nama kelas:

fill(data, 1.0);     // Mengisi semua elemen array data dengan nilai 1.0


Menginisialisasi Variabel Array
Anda dapat menginisialisasi sebuah variabel array dengan sebuah referensi ke array yang telah ada. Sebagai contoh, Anda dapat mendeklarasikan dua variabel berikut:

long[] genap = {2L, 4L, 6L, 8L, 10L};
long[] nilai = genap;

Di sini, referensi array yang disimpan pada genap dipakai untuk menginisialisasi array nilai. Efeknya ditampilkan pada Gambar 4-3.

Gambar 4-3

Anda menciptakan dua variabel array, tetapi Anda hanya memiliki satu array. Kedua variabel array mereferensi elemen-elemen yang sama. Salah satu kegunaannya adalah ketika Anda menukar array-array yang direferensi oleh dua variabel. Jika Anda mengurutkan sebuah array dengan secara berulang memindahkan elemen-elemen dari satu array ke array lain, Anda bisa menggunakan kode yang sama. Misalnya, jika Anda mendeklarasikan variabel-variabel array sebagai:

double[] arrayMasukan = new double[100];        // Array yang akan diurutkan
double[] arrayKeluaran = new double[100];       // Array hasil pengurutan
double[] temp;

ketika Anda ingin menukar array yang direferensi oleh arrayKeluaran menjadi array masukan baru, Anda dapat menuliskan:

temp = arrayMasukan; // Menyimpan referensi ke
arrayMasukan = arrayKeluaran; // Menetapkan arrayMasukan mereferensi ke arrayKeluaran
arrayKeluaran = temp;      // Menetapkan arrayKeluaran untuk mereferensi ke apa yang
                              sebelumnya adalah arrayMasukan

Tidak ada elemen array yang berpindah di sini. Hanya alamat array yang ditukar, jadi ini merupakan proses yang sangat cepat.


Menggunakan Array
Anda dapat menggunakan elemen-elemen array pada ekspresi dengan cara sama ketika Anda menggunakan variabel biasa. Sebagai contoh, jika Anda mendeklarasikan sebuah array cuplik, Anda dapat mengisinya dengan nilai-nilai acak antara 0.0 dan 100.0 dengan kode berikut:

double[] cuplik = new double[50];               // Sebuah array dengan 50 nilai double
for(int i = 0; i < cuplik.length; i++) {
   cuplik[i] = 100.0*Math.random();             // Membangkitkan nilai-nilai acak
}

Ini menunjukkan bagaimana loop for numerik sangat ideal ketika dipakai untuk mengisi elemen-elemen array. Tentu, ini bukan tanpa perencanaan. Alasan utama dihadirkannya loop for dalam Java adalah untuk beriterasi atas elemen-elemen array.

Untuk menunjukkan bahwa elemen-elemen array dapat dipakai dengan cara sama seperti variabel biasa, Anda dapat menuliskan statemen berikut:

double hasil = (cuplik[10]*cuplik[0] – Math.sqrt(cuplik[49]))/cuplik[29];

Ini merupakan sembarang perhitungan. Yang lebih masuk akal, untuk menghitung rerata atas nilai-nilai yang disimpan pada array cuplik dapat dituliskan berikut:

double rerata = 0.0; // Variabel untuk memuat nilai rerata

for(int i; i <cuplik.length; i++)
   rerata +=cuplik[i];     // Menjumlahkan semua elemen array
}
rerata /= cuplik.length;   // Membagi dengan banyak elemen total

Di dalam loop, Anda mengakumulasi penjumlahan atas semua elemen array cuplik dan menyimpan hasilnya ke dalam variabel rerata. Anda kemudian membagi hasil penjumlahan ini dengan banyak elemen array.

Perhatikan bagaimana Anda menggunakan panjang array, cuplik.length, di dua tempat pada program. Panjang array ditempatkan pada loop for dan sebagai pembagi untuk menghitung rerata.


Menggunakan Loop for Berbasis Koleksi Pada Array
Anda dapat menggunakan loop for berbasis koleksi sebagai cara alternatif ketika Anda ingin memproses nilai dari semua elemen array. Sebagai contoh, Anda bisa menuliskan ulang fragmen kode sebelumnya yang menghitung rerata array cuplik menjadi seperti ini:

double rerata = 0.0; // Variabel untuk memuat nilai rerata

for(double nilai : cuplik)
   rerata +=nilai;          // Menjumlahkan semua elemen array
}
rerata /= cuplik.length;   // Membagi dengan banyak elemen total

Loop for ini akan beriterasi melalui nilai dari semua elemen bertipe double pada array cuplik secara berurutan. Variabel nilai akan ditugasi nilai dari tiap elemen array cuplik secara bergiliran. Jadi, loop ini mendapatkan hasil sama seperti loop for numerik yang Anda gunakan sebelumnya, yaitu penjumlahan atas elemen-elemen yang diakumulasi pada rerata. Tentu, jika Anda hanya ingin memproses sebagian data dari array, Anda tetap harus menggunakan loop for numerik dengan pencacah loop dengan rentang indeks yang ingin diproses.

Penting untuk diingat bahwa loop for berbasis koleksi beriterasi melalui nilai-nilai yang disimpan pada sebuah array. Loop jenis ini tidak memberikan akses dengan tujuan menetapkan nilai-nilai elemen array. Oleh karena itu, Anda menggunakannya hanya ketika Anda mengakses semua nilai yang disimpan pada array.


Latihan
Lebih Lanjut Dengan Prima
Ketikkan kode berikut, yang diderivasi sebagian dari kode pada Bab 3:

import static java.lang.Math.ceil;
import static java.lang.Math.sqrt;

public class LanjutPrima {
   public static void main(String[] args) {
      long[] prima = new long[20]; // Array untuk menyimpan nilai-nilai prima
      prima[0] = 2L; // Nilai prima pertama
      prima[1] = 3L; // dan kedua

      int cacah = 2; // Banyak prima yang ditemukan sejauh ini,
                     // yang juga merupakan indeks array
                    
      long angka = 5L; // Integer berikutnya yang diuji

      luar:
      for( ; cacah < prima.length; angka += 2L) {
         // Pembagi maksimum yang perlu dicoba adalah akar kuadrat dari angka
         long limit = (long)ceil(sqrt((double)angka));

         // Membagi dengan semua prima sampai limit
         for(int i = 1; i < cacah && prima[i] <= limit; i++) {
            if(angka%prima[i] == 0L) { // Apakah pembagian habis tanpa sisa?
               continue luar; // Ya, jadi coba angka selanjutnya
            }
         }
        
         prima[cacah++] = angka; // Ditemukan satu prima!
      }

      for(long n : prima) {
         System.out.println(n); // Menampilkan semua prima
      }
   }
}

Penjelasan
Sembarang nilai yang bukan prima pastilah perkalian dari faktor-faktor prima, jadi Anda hanya perlu membagi sebuah kandidat prima dengan nilai-nilai prima yang kurang dari atau sama dengan akar kuadrat dari kandidat prima untuk menguji keprimaannya. Untuk setiap faktor yang dimiliki sebuah nilai yang lebih besar dari akar kuadrat dari nilai tersebut, hasil pembagian dengan faktor ini adalah faktor lain yang bernilai kurang dari akar kuadratnya. Misalnya, nilai 24 memiliki akar kuadrat yang sedikit lebih rendah dari 5. Anda dapat memfaktorkannya sebagai 2*12, 3*8, 4*6; kemudian Anda menemukan kasus-kasus dimana faktor pertama lebih besar dari akar kuadratnya, sehingga pemfaktoran berikutnya adalah 6*4, 8*3, dan seterusnya. Jadi, Anda mengulangi pasangan-pasangan faktor yang telah Anda miliki.

Anda lebih dahulu mendeklarasikan array prima sebagai tipe long, dan mendefinisikannya untuk memiliki 20 elemen. Anda menetapkan dua elemen pertama dari array prima menjadi 2 dan 3, untuk mengawali proses, karena Anda akan menggunakan nilai-nilai prima yang Anda miliki pada array sebagai pembagi ketika menguji kandidat prima yang baru.

Variabel cacah adalah banyak total prima yang telah ditemukan, jadi nilainya 2 karena Anda telah memiliki 2 dan 3 pada dua elemen pertama dari array prima. Perhatikan bahwa karena Anda menggunakan cacah sebagai variabel kendali loop for, Anda menghilangkan ekspresi pertama yang ada di dalam kurung pada statemen loop, karena nilai awal cacah telah ditetapkan.

Anda menyimpan kandidat prima yang akan diuji pada variabel angka, dengan nilai pertama ditetapkan 5. Pertama-tama, variabel cacah yang menentukan kapan loop berakhir tidak diinkremen pada statemen loop for, tetapi di dalam tubuh loop. Anda menggunakan ekspresi pengendali ketiga dari loop for untuk menginkremen angka dengan langkah 2, karena Anda tidak ingin memeriksa nilai-nilai genap. Loop for berakhir ketika cacah sama dengan panjang array. Anda menguji nilai pada angka pada loop for terdalam dengan membagi angka dengan semua nilai prima yang Anda miliki pada array prima yang bernilai kurang dari atau sama dengan akar kuadrat dari kandidat prima. Jika Anda memperoleh pembagian habis tanpa sisa, maka nilai pada angka bukanlah bilangan prima, jadi kendali program melompat ke iterasi selanjutnya dari loop luar melalui statemen continue.

Anda menghitung batas untuk pembagi dengan statemen berikut:

long limit = (long) ceil(sqrt((double)angka));

Metode sqrt() dari kelas Math menghasilkan akar kuadrat atas angka sebagai sebuah nilai double, jadi jika angka memiliki nilai 7, misalnya, maka 2.64575 akan dihasilkan. Nilai ini akan dilewatkan kepada metode ceil(), yang merupakan anggota dari kelas Math. Metode ceil() menghasilkan sebuah nilai bertipe double, yang merupakan bilangan bulat minimum yang bernilai tidak kurang dari nilai yang dilewatkan. Dengan angka bernilai 7, metode ini akan menghasilkan 3.0, nilai bulat terkecil yang tidak kurang dari akar kuadrat atas 7. Anda menggunakan nilai ini sebagai batas pembagi integer, sehingga Anda melakukan konversi tipe eksplisit menjadi tipe long dan menyimpan hasilnya pada limit.

Jika Anda tidak mendapatkan pembagian tanpa sisa, program akan keluar secara normal dari loop terdalam dan mengeksekusi statemen:

prima[cacah++] = angka; // Ditemukan satu prima!

Variabel cacah digunakan untuk menyimpan banyak prima yang telah ditemukan. Selain itu, cacah juga  dipakai sebagai indeks untuk elemen array prima.

Ketika Anda telah selesai mengisi array prima, loop luar akan berakhir dan Anda menampilkan semua nilai pada array dengan loop berikut:

for(long n : prima) {
   System.out.println(n); // Menampilkan semua prima
}

Loop ini beriterasi melalui semua elemen bertipe long pada array prima secara berurutan. Pada tiap iterasi, n akan memuat nilai dari elemen terkini.

Anda dapat mengekspresikan proses logikal dari program ini dengan langkah-langkah berikut:
1.      Ambil angka yang diuji dan tentukan akar kuadratnya.
2.      Tetapkan limit untuk pembatas sebagai integer terkecil yang lebih besar dari akar kuadrat atas angka.
3.      Uji apakah angka dapat dibagi habis tanpa sisa oleh semua prima yang telah ada pada array prima yang bernilai kurang dari limit sebagai pembagi.
4.      Jika angka dapat dibagi habis tanpa sisa oleh semua prima yang telah ada pada array prima, buang angka tersebut dan awali iterasi baru dari loop dengan kandidat prima berikutnya.
5.      Jika pembagian oleh semua pembagi menghasilkan sisa, maka angka adalah bilangan prima. Kemudian, iterasi selanjutnya akan menguji kandidat prima yang baru.
6.      Ketika array prima telah penuh, tampilkan semua bilangan prima yang didapatkan.


Array yang Memuat Array-Array
Anda telah menggunakan array-array satu-dimensi sampai saat ini, yaitu array-array yang menggunakan satu indeks. Mengapa Anda memerlukan lebih dari satu indeks untuk mengakses elemen array?

Dimisalkan Anda tertarik tentang cuara, dan Anda bermaksud untuk merekam temperatur setiap hari pada 10 tempat berbeda selama setahun. Jadi, Anda akan memerlukan sebuah array yang memuat 10 elemen yang berkaitan dengan banyak lokasi pengukuran, dimana tiap elemen array merupakan sebuah array dengan 365 elemen untuk menyimpan nilai-nilai temperatur. Anda mendeklarasikan array ini dengan statemen:

float[][] temperatur = new float[10][365];

Ini dinamakan dengan array dua-dimensi, karena memiliki dua dimensi: satu dimensi dengan nilai indeks dari 0 sampai 9, dan dimensi lain dengan nilai indeks dari 0 sampai 364. Indeks pertama berelasi dengan lokasi pengukuran, dan indeks kedua berkaitan dengan banyak hari pengukuran dalam setahun. Gambar 4-4 menunjukkan struktur array dua-dimensi ini.

Gambar 4-4

Ada 10 array satu-dimensi yang membangun array dua-dimensi di sini, dan masing-masing array satu-dimensi tersebut memiliki 365 elemen. Dalam mengakses sebuah elemen array dua-dimensi, sepasang kurung siku pertama mengapit indeks untuk array tertentu dan sepasang kurung siku kedua mengapit nilai indeks untuk elemen di dalam array tersebut. Jadi, untuk mengakses temperatur pada hari 100 untuk lokasi pengukuran keenam, Anda menggunakan temperator[5][99]. Karena tiap variabel float menempati 4 byte memori, memori total yang diperlukan untuk array dua-dimensi ini adalah 10x365x4 byte, atau sama dengan 14600 byte.

Anda juga bisa menggunakan dua statemen untuk menciptakan array temperatur, satu statemen untuk mendeklarasikan variabel array dan statemen lainnya untuk mendefinisikan array:

float[][] temperatur;                    // Mendeklarasikan variabel array
temperatur = new float[100][365];        // Menciptakan array

Statemen pertama mendeklarasikan variabel array temperatur untuk array dua-dimensi dengan tipe float. Statemen kedua menciptakan array dengan 10 elemen, dengan tiap elemen merupakan sebuah array yang memuat 365 elemen bertipe float.


Latihan
Pengukuran Cuaca
Anda akan menghitung rerata temperatur tahunan pada sepuluh lokasi berbeda. Temperatur yang direkam diukur dalam derajat Celcius.

public class RerataTemperatur {
   public static void main(String[] args) {
      float[][] temperatur = new float[10][365]; // Array temperatur

      // Membangkitkan temperatur-temperatur acak
      for(int i = 0; i<temperatur.length; i++) {
         for(int j = 0; j < temperatur[i].length; j++) {
            temperatur[i][j] = (float)(45.0*Math.random() - 10.0);
         }
      }

      // Menghitung rerata per lokasi pengukuran
      for(int i = 0; i<temperatur.length; i++) {
         float rerata = 0.0f; // Tempat menyimpan rerata
            for(int j = 0; j < temperatur[i].length; j++) {
               rerata += temperatur[i][j];
            }

         // Menampilkan rerata temperatur untuk lokasi terkini
         System.out.println("Rerata temperatur pada lokasi "
            + (i+1) + " = " + rerata/(float)temperatur[i].length);
      }
   }
}

Keluaran program:

Rerata temperatur pada lokasi 1 = 13.236053
Rerata temperatur pada lokasi 2 = 12.42325
Rerata temperatur pada lokasi 3 = 13.320883
Rerata temperatur pada lokasi 4 = 12.546554
Rerata temperatur pada lokasi 5 = 12.3035145
Rerata temperatur pada lokasi 6 = 12.437321
Rerata temperatur pada lokasi 7 = 13.090304
Rerata temperatur pada lokasi 8 = 12.551801
Rerata temperatur pada lokasi 9 = 12.768845
Rerata temperatur pada lokasi 10 = 12.825517

Penjelasan
Setelah mendeklarasikan array temperatur, Anda mengisinya dengan nilai-nilai acak menggunakan loop for. Perhatikan bagaimana temperatur.length dipakai pada loop terluar untuk mengakses panjang dari dimensi pertama, 10 pada kasus ini. Pada loop terdalam, Anda menggunakan temperatur[i].length untuk mengakses panjang dari dimensi kedua, 365 pada kasus ini.

Metode Math.random() membangkitkan sebuah nilai bertipe double antara dari 0.0 dan 1.0 (tidak termasuk 1.0). Nilai ini dikalikan dengan 45.0 pada ekspresi untuk temperatur, yang menghasilkan nilai-nilai antara 0.0 dan 45.0. Dengan mengurangkan 10.0 dari nilai ini, Anda akan memperoleh rentang nilai yang diperlukan -10.0 sampai 35.0.

Anda kemudian menggunakan sepasang loop for bersarang lain, yang dikendalikan dengan cara sama seperti yang pertama, untuk menghitung rerata dari temperatur-temperatur yang disimpan. Loop terluar beriterasi melalui lokasi-lokasi dan loop terdalam menjumlahkan semua nilai temperatur untuk lokasi tertentu. Sebelum loop terdalam dieksekusi, variabel rerata dideklarasikan dan diinisialisasi, dan ini dipakai untuk mengakumulasi hasil penjumlahan atas tiap temperatur pada lokasi pengukuran tertentu pada loop terdalam.

Setelah loop terdalam dieksekusi, Anda menampilkan rerata temperatur untuk tiap lokasi pengukuran, dengan nomor lokasi 1 sampai 10, dengan satu lebih besar dari nilai indeks dari tiap lokasi. Untuk mendapatkan rerata, Anda membagi variabel rerata dengan banyak cuplik, yaitu temperatur[i].length, yang merupakan panjang array yang memuat nilai-nilai temperatur pada lokasi terkini.

Anda dapat menuliskan loop bersarang berbasis koleksi untuk menghitung rerata temperatur sebagai berikut:

int lokasi = 0;     
// Menghitung rerata per lokasi pengukuran
for(float[] temperatur1D : temperatur) {
   float rerata = 0.0f; // Tempat menyimpan rerata
   for(float t : temperatur1D) {
      rerata += t;
   }

// Menampilkan rerata temperatur untuk lokasi terkini
System.out.println("Rerata temperatur pada lokasi "
            + (++lokasi) + " = " + rerata/(float) temperatur1D.length);
      }

Loop terluar beriterasi melalui elemen-elemen pada array yang memuat array-array, jadi variabel loop temperatur1D akan mereferensi tiap array satu-dimensi pada temperatur secara bergiliran. Tipe data dari variabel temperatur1D adalah float[] karena ia menyimpan sebuah referensi ke sebuah array satu-dimensi dari array yang memuat array-array satu-dimensi, temperatur.


Array yang Memuat Array-Array dengan Panjang Berbeda
Ketika Anda menciptakan sebuah array yang memuat array-array, array-array tersebut tidak harus memiliki panjang sama. Anda dapat mendeklarasikan sebuah variabel array, cuplik, dengan statemen:

float[][] cuplik;    // Mendeklarasikan sebuah array yang memuat array-array

Ini mendeklarasikan objek array cuplik dengan tipe float[][]. Anda kemudian dapat mendefinisikan banyak elemen pada dimensi pertama dengan statemen:

cuplik = new float[6][];   // Mendefinisikan 6 elemen, tiap elemen adalah sebuah array

Variabel cuplik sekarang mereferensi sebuah array dengan enam elemen, yang masing-masing dapat memuat sebuah referensi ke array satu-dimensi. Anda dapat mendefinisikan array-array ini secara individual jika Anda inginkan:

cuplik[2] = new float[6];         // Array ketiga memiliki 6 elemen
cuplik[5] = new float[100]; // Array keenam memiliki 100 elemen

Ini mendefinisikan dua dari enam array satu-dimensi yang dapat direferensi melalui elemen-elemen dari array cuplik. Elemen ketiga pada array cuplik sekarang mereferensi sebuah array dengan 6 elemen bertipe float, dan elemen keenam pada array cuplik sekarang mereferensi sebuah array dengan 100 elemen bertipe float. Tentu, Anda tidak dapat menggunakan sebuah array sampai array tersebut didefinisikan.

Jika Anda menginginkan agar array cuplik memiliki bentuk segitiga, dengan satu elemen pada baris pertama, dua elemen pada baris kedua, tiga elemen pada baris ketiga , dan seterusnya, maka Anda dapat mendefinisikan array-array pada sebuah loop:

for(int i = 0; i < cuplik.length; i++) {
   cuplik[i] = new float[i+1];           // Mengalokasikan tiap array
}

Efeknya akan menghasilkan tataletak array yang ditampilkan pada Gambar 4-5.

Anda dapat menggunakan sebuah look for numerik untuk menginisialisasi elemen-elemen pada array cuplik, meskipun baris-barisnya berbeda panjang:

for(int i = 0; i < cuplik.length; i++) {
   for(int j = 0; j < cuplik[i].length; j++) {
      cuplik[i][j] = 99.0f; // Menginisialisasi tiap elemen dengan nilai 99
   }
}

Batas atas untuk variabel kendali pada loop sebelah-dalam adalah cuplik[i].length. Ekspresi cuplik[i] mereferensi baris terkini pada array dua-dimensi jadi cuplik[i].length adalah banyak elemen pada baris terkini. Loop sebelah-luar beriterasi melalui baris-baris pada array cuplik, dan loop sebelah-dalam beriterasi melalui semua elemen pada sebuah baris.

Gambar 4-5

Anda dapat pula mendapatkan hasil sama dengan kode yang lebih ringkas menggunakan metode fill() dari kelas Arrays berikut:

for(int i = 0; i < cuplik.length; i++) {
   java.util.Arrays.fill(cuplik[i], 99.0f);  // Menginisialisasi tiap elemen dengan nilai 99
}

Karena metode fill() mengisi semua elemen pada sebuah baris, Anda hanya memerlukan satu loop untuk beriterasi melalui baris-baris dari array.


Array Multidimensi
Anda tidak dibatasi hanya memiliki array dua-dimensi. Jika Anda dapat mendeklarasikan seubah array tiga-dimensi, seperti berikut:

long[][][] array3D = new long[3][][];    // Tiga buah array dua-dimensi

Array array3D memiliki tiga dimensi. Array ini terdiri-dari tiga elemen, yang masing-masing elemen dapat memuat array dua-dimensi yang berbeda ukuran. Anda bisa menetapkan dimensi pertama dari tiap elemen secara eksplisit dengan statemen-statemen berikut:

array3D[0] = new long[4][];
array3D[1] = new long[2][];
array3D[2] = new long[5][];

Ketiga array ini memiliki elemen-elemen yang masing-masing memuat sebuah array satu-dimensi, dan Anda dapat pula menetapkan ukuran dari array satu-dimensi itu secara independen. Perhatikan bagaimana kurung-siku mengindikasikan bahwa masih ada dimensi yang tak didefinisikan.


Array yang Memuat Karakter-Karakter
Semua array yang Anda telah definisikan sejauh ini memuat elemen-elemen yang menyimpan nilai-nilai numerik. Anda dapat juga memiliki array yang memuat karakter-karakter. Misalnya, Anda dapat mendeklarasikan sebuah variabel array bertipe char[] untuk menampung 50 karakter dengan statemen berikut:

char[] pesan = new char[50];

Ingat bahwa karakter-karakter disimpan sebagai Unicode dalam Java, jadi tiap elemen menempati 2 byte memori.

Jika Anda ingin menginisialisasi tiap elemen array ini dengan karakter spasi, maka Anda dapat menggunakan loop for untuk beriterasi melalui elemen-elemen array, atau cukup menggunakan metode fill() pada kelas Arrays, seperti ini:

java.util.Arrays.fill(pesan, ‘ ‘); // Menyimpan spasi pada tiap elemen array

Tentu, Anda dapat menggunakan metode fill() untuk menginisialisasi elemen-elemen dengan karakter apapun yang Anda inginkan. Jika Anda menempatkan ‘\n’ sebagai argumen kedua pada metode fill(), elemen-elemen array semuanya akan memuat karakter baris-baru.

Anda dapat pula mendefinisikan ukuran dari array bertipe char[] berdasarkan karakter-karakter yang dimuatnya:

char[] vokal = {‘a’, ‘e’, ‘i’, ‘o’, ‘u’};

Ini mendefinisikan sebuah array dengan lima elemen, yang diinisialisasi dengan karakter-karakter yang ada di dalam kurung-kurawal.


String
Anda akan memubutuhkan string karakter pada program-program Anda. Dalam Java, string biasa adalah objek dari kelas String. Kelas String adalah sebuah kelas standar dalam Java yang dirancang secara khusus untuk menciptakan dan memproses string. Definisi dari kelas String ada dalam paket java.lang, jadi kelas tersebut secara otomatis tersedia bagi program Anda secara default.




Literal String
Anda sejauh ini telah banyak menggunakan literal string dalam program. Hampir setiap kali metode println() pada contoh dipakai, Anda menggunakan literal string sebagai argumennya. Literal string adalah sebuah runtun karakter yang diapit di antara dua tanda-kutip ganda:

“Ini adalah sebuah literal string!”

Ini sebenarnya adalah sebuah literal String dengan huruf besar S, yang merupakan sebuah objek konstan dari kelas String yang diciptakan kompilator pada program Anda.

Seperti disebutkan pada Bab 2, sejumlah karakter tidak dapat dimasukkan secara eksplisit dari keyboard jadi Anda tidak dapat mencantumkannya secara langsung pada sebuah literal string. Anda tidak bisa mencantumkan sebuah karakter baris-baru dengan menekan kunci Enter karena hal itu akan memindahkan kursor ke baris baru. Anda juga tidak bisa mencantumkan sebuah karakter kutip-ganda pada literal string secara langsung karena karakter tersebut dipakai untuk mengindikasikan di mana sebuah literal string diawali dan diakhiri. Anda dapat menetapkan semua karakter ini pada sebuah string seperti yang Anda lakukan untuk konstanta Char pada Bab 2, yaitu Anda menggunakan runtun escape. Semua runtun escape yang dipakai pada konstanta Char juga berlaku untuk string.

Statemen:

 System.out.println(“Ini adalah \nsebuah konstanta string!”);

akan menghasilkan:

Ini adalah
sebuah konstanta string!

karena \n diinterpretasikan sebagai sebuah karakter baris-baru. Seperti nilai bertipe Char, string disimpan secara internal sebagai karakter-karakter Unicode. Anda dapat pula mencantumkan kode karakter Unicode pada sebuah string sebagai runtun escape dengan format \unnnn dimana nnnn merupakan empat dijit heksadesimal dari kode Unicode untuk karakter tertentu. Huruf Yunani , misalnya, adalah \u03C0.


Menciptakan Objek String
Untuk memastikan tidak ada kebingungan bagi Anda, variabel String merupakan sebuah variabel yang menyimpan sebuah referensi ke suatu objek dari kelas String. Anda mendeklarasikan sebuah variabel String dengan cara sama seperti Anda mendefinisikan variabel bertipe primitif. Anda dapat pula menginisialisasinya pada deklarasi:

String stringKu = “Objek kelas String.”;

Ini mendeklarasikan variabel stringKu sebagai tipe String dan menginisialisasinya dengan sebuah referensi ke suatu objek String yang memuat string “Objek kelas String.”. Anda dapat menyimpan sebuah referensi ke string lain pada sebuah variabel String, menggunakan statemen penugasan. Sebagai contoh, Anda dapat mengubah nilai dari variabel String, stringKu, menjadi:

stringKu = “Objek String diubah!.”;

Efeknya diilustrasikan pada Gambar 4-6.

Gambar 4-6

Objek String itu sendiri berbeda dari variabel yang Anda pakai untuk mereferensi atau mengaksesnya. Dengan cara sama pada objek array, variabel stringKu menyimpan sebuah referensi ke suatu objek String, bukan objek itu sendiri, jadi dengan kata lain, sebuah variabel String menyimpan lokasi di mana objek String berada di dalam memori. Ketika Anda mendeklarasikan dan menginisialisasi stringKu, variabel itu mereferensi objek yang merupakan literal string penginisialisasi. Ketika statemen penugasan itu dieksekusi, referensi semula digantikan oleh referensi ke string baru dan string lama akan dibuang. Variabel stringKu kemudian memuat sebuah referensi ke string baru.

Objek String dikatakan immutable, yang berarti bahwa ia tidak dapat diubah. Ini berarti bahwa Anda tidak memodifikasi objek String. Ketika Anda mengeksekusi sebuah statemen yang menggabungkan objek-objek String yang telah ada, Anda sebenarnya sedang menciptakan sebuah objek String baru sebagai hasilnya. Ketika Anda mengubah string yang direferensi oleh sebuah variabel String, Anda membuang referensi ke string lama dan menggantinya dengan sebuah referensi ke string baru. Perbedaan antara variabel String dan string yang direferensinya memang tidak nyata bagi Anda sejauh ini, tetapi Anda nanti akan melihat pada bab ini bahwa pemahaman ini penting untuk diperhatikan.

Anda perlu mengingat bahwa karakter-karakter pada sebuah string adalah karakter-karakter Unicode, jadi tiap karakter umumnya menempati 2 byte memori, dengan kemungkinan adanya karakter menempati 4 byte jika Anda menggunakan karakter-karakter yang direpresentasikan sebagai surrogate. Memang hal ini tidak perlu dikhawatirkan pada hampir semua situasi, tetapi ada sejumlah kesempatan dimana Anda perlu menyadarinya.

Tentu, Anda dapat mendeklarasikan sebuah variabel bertipe String tanpa menginisialisasinya:

String sembarangString;    // Variabel String tak-terinisialisasi

Variabel sembarangString yang telah Anda deklarasikan di sini tidak mereferensi apapun. Namun, jika Anda mencoba mengkompilasi sebuah program yang mencoba menggunakan sembarangString sebelum ia diinisialisasi dengan cara tertentu, Anda akan mendapatkan error kompilasi. Jika Anda tidak menginginkan sebuah variabel String untuk mereferensi sesuatu, Anda perlu menginisialisasinya dengan nilai null:

String sembarangString = null;    // Variabel String yang tidak mereferensi sebuah string

Literal null adalah sebuah nilai referensi objek yang tidak menunjuk ke apapun. Karena array sebenarnya adalah objek, Anda juga dapat menggunakan null sebagai nilai bagi sebuah variabel array.

Anda dapat menguji apakah sebuah variabel String mereferensi sesuatu atau tidak menggunakan statemen semacam ini:

if(sembarangString == null) {
   System.out.println(“sembarangString tidak mereferensi apapun!”);
}

Variabel sembarangString akan tetap bernilai null sampai Anda menggunakan sebuah statemen penugasan untuk membuatnya mereferensi string tertentu. Jika Anda mencoba menggunakan sebuah variabel yang belum diinisialisasi, error kompilasi akan terjadi.

Anda dapat menggunakan literal null ketika Anda ingin membuang sebuah objek String yang sedang direferensi oleh suatu variabel. Dimisalnya Anda mendefinisikan sebuah variabel String seperti ini:

String pesan = “Baik hari ini jauh lebih baik daripada sempurna esok”;

Pada titik berikutnya pada program, Anda ingin membuang string yang direferensi pesan. Anda bisa menuliskan statemen ini:

pesan = null;

Nilai null menggantikan referensi semula yang disimpan sehingga pesan sekarang tidak mereferensi apapun.


Array String
Anda dapat menciptakan array string. Anda mendeklarasikan sebuah array yang memuat objek-objek String dengan mekanisme sama seperti ketika Anda mendeklarasikan array yang memuat elemen-elemen bertipe data primitif. Anda hanya perlu menggunakan tipe String pada deklarasi. Misalnya, untuk mendeklarasikan sebuah array dengan lima objek String, Anda menggunakan statemen:

String[] nama = new String[5];

Anda dapat memerhatikan bahwa argumen pada metode main() adalah sebuah array yang memuat objek-objek String karena definisi metode selalu tampak seperti ini:

public static void main(String[] args) {
   // Kode untuk metode…
}

Anda dapat pula mendeklarasikan sebuah array yang memuat objek-objek String dimana nilai-nilai awal menentukan ukuran array:

String[] warna = {“merah”, “oranye”, “kuning”, “hijau”, “biru”, “indigo”, “violet”};

Array ini memiliki tujuh elemen karena terdapat 7 literal string penginisialisasi yang ada di dalam kurung-kurawal.


Latihan
Twinkle, Twinkle, Lucky Star
Anda akan menciptakan sebuah program konsol untuk membangkitkan bintang film Anda hari ini:

public class BintangFilm {
   public static void main(String[] args) {
      String[] bintang = {"Robert Redford" , "Marilyn Monroe",
                        "Boris Karloff" , "Lassie",
                        "Hopalong Cassidy", "Trigger"};
                        
      System.out.println("Bintang film Anda hari ini adalah "
         + bintang[(int)(bintang.length*Math.random())]);
   }
}

Ketika Anda mengkompilasi dan menjalankan program ini, hasilnya akan berubah sesuai dengan peruntungan Anda:

Bintang film Anda hari ini adalah Lassie

Penjelasan
Program ini menciptakan array bintang bertipe String[]. Panjang array akan ditetapkan berdasarkan berapa banyak nilai inisialisasi yang ada di dalam kurung-kurawal pada statemen deklarasi, pada kasus ini 6.

Anda memilih sebuah elemen acak dari array dengan menciptakan nilai indeks acak pada statemen keluaran dengan ekspresi (int)(bintang.length*Math.random()). Pengalian nilai acak yang dihasilkan metode Math.random() dengan panjang array akan menghasilkan sebuah nilai antara 0.0 dan 6.0 karena nilai yang dihasilkan random() berada antara 0.0 dan 1.0. Hasilnya kemudian dikonversi menjadi tipe int dan akan menghasilkan sebuah nilai dari 0 sampai 5, yang membuatnya menjadi nilai indeks valid untuk array bintang.

Jadi, program memilih sebuah string acak dari array dan menampilkannya, sehingga Anda dapat melihat keluaran berbeda ketika Anda mengeksekusi program secara berulang.


Operasi-Operasi pada String
Ada banyak jenis operasi yang dapat dilakukan terhadap string, tetapi Anda akan mengawalinya dengan apa yang telah Anda gunakan: penggabungan dua atau lebih string untuk membentuk sebuah string kombinasi baru. Operasi ini dinamakan dengan penyambungan string.


Penyambungan String
Untuk menggabung atau menyambung objek-objek String agar membentuk sebuah string baru, Anda menggunakan operator +, sama seperti yang Anda lakukan pada argumen untuk metode println() pada contoh-contoh program sejauh ini. Penggunaan paling sederhana dari operasi + adalah untuk menyambung dua string:

stringKu = “Penyambungan dua string” + “ untuk menghasilkan string baru.”;

Ini akan menyambung dua string yang ada di sebelah kanan penugasan dan menyimpan hasilnya pada variabel String, pada kasus ini stringKu. Operasi + menghasilkan sebuah objek String yang sama sekali baru yang terpisah dari dua objek String semula yang menjadi operand, dan objek baru ini disimpan pada stringKu. Tentu, Anda juga bisa menggunakan operator + untuk penjumlahan aritmatik. Tetapi, jika salah satu atau kedua operand dari operator + adalah objek atau literal String, maka kompilator akan menginterpretasikannya sebagai operasi penyambungan string dan akan mengkonversi operand yang bukan objek String menjadi sebuah string.

Gambar 4-7

Berikut adalah sebuah contoh penyambungan string yang direferensi oleh variabel-variabel String:

String tanggal = “31 “;
String bulan = “Desember”;
String hariTerakhir = tanggal + bulan;   // Hasilnya adalah “31 Desember”

Jika sebuah variabel String yang Anda gunakan sebagai salah satu operand dari operator + memuat null, maka nilai null ini akan dikonversi secara otomatis menjadi string “null”. Jadi jika variabel bulan memuat null, bukan sebuah referensi ke string “Desember”, maka hasil penyambungan dengan tanggal akan menjadi string “31 null”.

Perhatikan bahwa Anda juga dapat menggunakan operator += untuk menyambung string-string. Sebagai contoh:

String frase = “Terlalu banyak”;
frase += “ pengetahuan membuatmu bingung”;

Setelah statemen-statemen ini dieksekusi, variabel frase akan mereferensi ke string “Terlalu banyak pengetahuan membuatmu bingung”. Tentu, ini tidak memodifikasi string “Terlalu banyak”. String yang direferensi oleh frase merupakan sebuah objek String yang baru. Ini diilustrasikan pada Gambar 4-7.

Anda akan melihat sejumlah variasi pada penggunaan operator + terhadap objek-objek String pada contoh berikut.

Latihan
Penyambungan String
Masukkan kode berikut untuk kelas SambungString:

public class SambungString {
   public static void main(String[] args) {
      String stringPertama = "Banyak ";
      String stringKedua = "tangan ";
      String stringKetiga = "membuat kerja ringan";
      String stringKu; // Variabel untuk menyimpan hasil

      // Menyambung tiga string dan menyimpan hasil
      stringKu = stringPertama + stringKedua + stringKetiga;
      System.out.println(stringKu);

      // Mengkonversi integer menjadi String dan menyambung dua string lain
      int bykTangan = 99;
      stringKu = bykTangan + " " + stringKedua + stringKetiga;
      System.out.println(stringKu);

      // Menyambung sebuah string dan integer-integer
      stringKu = "lima lima adalah "+ 5 + 5;
      System.out.println(stringKu);

      // Menyambung integer-integer dan sebuah string
      stringKu = 5 + 5 + " adalah sepuluh";
      System.out.println(stringKu);
   }
}

Keluaran program

Banyak tangan membuat kerja ringan
99 tangan membuat kerja ringan
lima lima adalah 55
10 adalah sepuluh

Penjelasan
Baris pertama pada keluaran cukup sederhana, yang merupakan penyambungan tiga nilai string yang disimpan pada variabel-variabel String, stringPertama, stringKedua, dan stringKetiga, menjadi sebuah string dan menyimpannya pada variabel stringKu.

Gambar 4-8

Baris kedua keluaran adalah penggunaan operator + seperti yang biasa Anda gunakan pada metode println(). Ini diilustrasikan pada Gambar 4-8.

Di balik layar, nilai dari variabel bykTangan dikonversi menjadi sebuah string yang merepresentasikan nilai ini sebagai sebuah nilai desimal. Ini terjadi akibat penggabungannya dengan literal string “ “. Operand dengan tipe data berbeda tidak bisa dioperasikan menggunakan operator biner (pada kasus ini, operator +), jadi salah satu operand harus dikonversi menjadi tipe data lain. Di sini, kompilator memutuskan bahwa nilai numerik yang disimpan pada variabel bykTangan dikonversi menjadi tipe String agar menyesuaikan tipe data dari operand kanan dari operator +. Jika Anda mengingat kembali tabel dari keutamaan operator, Anda akan melihat bahwa asosiatifitas dari operator + adalah dari kiri ke kanan, jadi string-string dikombinasikan atau disambuung diawali dari kiri, seperti ditunjukkan pada Gambar 4-8.

Asosiatifitas kiri-ke-kanan dari operator + penting dipahami pada dua baris keluaran selanjutnya. Dua statemen tersebut terlibat dalam menciptakan string-string yang tampak sangat mirip. Mengapa 5 + 5 menghasilkan 55 pada satu statemen, dan menghasilkan 10 pada statemen lain? Alasannya diilustrasikan pada Gambar 4-9.

Gambar 4-9

Perbedaan utama antara kedua statemen adalah bahwa statemen pertama selalu memiliki sedikitnya satu operand bertipe String, jadi operasi merupakan penyambungan string, sedangkan pada statemen kedua operasi pertama adalah operasi aritmatik numerik karena kedua operand merupakan integer. Pada statemen pertama, tiap integer dikonversi menjadi String secara individual. Pada statemen kedua, nilai-nilai numerika dijumlahkan, dan hasilnya 10, dikonversi menjadi sebuah representasi string yang kemudian disambungkan dengan “ adalah sepuluh”.

Anda tidak perlu mengetahuinya pada titik ini, tetapi jika Anda bertanya-tanya, konversi nilai-nilai bertipe primitif menjadi tipe String sebenarnya dilakukan oleh sebuah metode static, toString(), dari kelas standar. Tiap tipe primitif memiliki kelas ekivalen (wrapper), seperti ditunjukkan pada tabel berikut:

Tipe Dasar (Primitif)
Kelas Wrapper)
byte
Byte
short
Short
int
Integer
long
Long
float
Float
double
Double
boolean
Boolean
char
Character

Kelas-kelas pada tabel merupakan kelas wrapper karena objek dari kelas ini “membungkus” nilai bertipe primitif. Ketika sebuah nilai bertipe salah satu tipe primitif menjadi salah satu operand dari operator + dan operand lain bertipe String, kompilator akan melewatkan nilai bertipe primitif tersebut sebagai argumen kepada metode toString(). Metode toString() kemudian menghasilkan String ekivalen dari nilai itu. Semua ini terjadi secara otomatis ketika Anda menyambung dua string menggunakan operator +.

Kelas String juga mendefinisikan sebuah metode, valueOf(), yang akan menciptakan sebuah objek String dari suatu nilai bertipe primitif. Anda hanya perlu melewatkan nilai yang ingin Anda konversi menjadi string sebagai argumen kepada metode ini. Misalnya:

String stringDouble = String.valueOf(3.14159);

Anda memanggil metode valueOf menggunakan nama kelas String, seperti ditunjukkan pada statemen di atas. Ini karena metode tersebut adalah anggota static dari kelas String. Anda akan belajar apa itu static nanti pada Bab 5. Sembarang literal atau variabel bertipe primitif dapat dilewatkan kepada metode valueOf(), dan metode ini akan menghasilkan representasi String dari nilai tersebut.


Membandingkan String
Di sinilah perbedaan antara variabel String dan string yang direferensinya akan menjadi nyata bagi Anda. Untuk membandingkan kesamaan nilai yang disimpan pada dua variabel bertipe primitif, Anda menggunakan operator ==. Ini tidak berlaku pada objek String (atau objek lain). Ekspresi:

string1 == string2

akan memeriksa apakah kedua variabel String tersebut mereferensi string yang sama atau tidak. Jika mereferensi string yang berbeda, ekspresi ini akan menghasilkan nilai false. Dengan kata lain, ekspresi di atas tidak membandingkan string itu sendiri; ia membandingkan referensi ke string, jadi hasilnya akan bernilai true hanya jika string1 dan string2 keduanya mereferensi string yang tunggal dan sama. Anda dapat melihat hal ini pada contoh berikut:


Latihan
Dua String, Identik Tapi Tidak Sama
Pada kode berikut, Anda menguji untuk melihat apakah string1 dan string3 mereferensi ke string yang sama atau tidak:

public class BandingString {
   public static void main(String[] args) {
      String string1 = "Terlalu banyak ";
      String string2 = "pendapat";
      String string3 = "Terlalu banyak pendapat";

      // Membuat string1 dan string3 mereferensi ke string berbeda
      // yang identik
      string1 += string2;

      // Menampilkan isi dari string-string
      System.out.println("Uji 1");
      System.out.println("string3 sekarang adalah: " + string3);
      System.out.println("string1 sekarang adalah: " + string1);

      if(string1 == string3) // Sekarang uji identitas
         System.out.println("string1 == string3 bernilai true." +
            " string1 dan string3 menunjuk ke string sama");
      else
         System.out.println("string1 == string3 bernilai false." +
            " string1 dan string3 tidak menunjuk ke string sama");

      // Sekarang buat string1 dan string2 mereferensi ke string sama
      string3 = string1;

      // Menampilkan isi dari string-string
      System.out.println("\n\nUji 2");
      System.out.println("string3 sekarang adalah: " + string3);
      System.out.println("string1 sekarang adalah: " + string1);
     
      if(string1 == string3) // Sekarang uji identitas
         System.out.println("string1 == string3 bernilai true." +
            " string1 dan string3 menunjuk ke string sama");
      else
         System.out.println("string1 == string3 bernilai false." +
            " string1 dan string3 tidak menunjuk ke string sama");
   }
}

Keluaran program:
Anda telah menciptakan dua skenario pada contoh ini. Pertama, variabel string1 dan string3 mereferensi ke objek-objek String terpisah yang memuat string identik. Kedua, kedua variabel tersebut mereferensi objek String yang sama.

Uji 1
string3 sekarang adalah: Terlalu banyak pendapat
string1 sekarang adalah: Terlalu banyak pendapat
string1 == string3 bernilai false. string1 dan string3 tidak menunjuk ke string sama

Uji 2
string3 sekarang adalah: Terlalu banyak pendapat
string1 sekarang adalah: Terlalu banyak pendapat
string1 == string3 bernilai true. string1 dan string3 menunjuk ke string sama

Penjelasan
Ketiga variabel string1, string2, dan string3 diinisialisasi dengan literal-literal string yang Anda lihat pada program. Setelah statemen penugasan dieksekusi, string yang direferensi oleh string1 akan identik dengan string yang direferensi oleh string3, tetapi seperti yang Anda lihat dari keluaran program, perbandingan ekualitas pada statemen if menghasilkan false karena kedua variabel tersebut mereferensi dua string terpisah.

Selanjutnya Anda mengubah nilai dari string3 sehingga ia mereferensi string yang sama dengan string1. Keluaran program menunjukkan bahwa ekspresi if memiliki nilai true, dan bahwa objek string1 dan objek string3 keduanya merefrensi ke string yang sama.


Membandingkan Ekualitas String
Untuk membandingkan dua variabel String, yaitu untuk memutuskan apakah string-string yang direferensinya sama atau tidak, Anda harus menggunakan metode equals(), yang didefinisikan untuk objek-objek bertipe String. Misalnya, untuk membandingkan objek-objek String yang direferensi oleh variabel string1 dan string3, Anda dapat menuliskan statemen:

if(string1.equals(string3)) {
   System.out.println(“string1.equals(string3) bernilai true. “ +
       “ jadi kedua string sama.”);
}

Ini akan memanggil metode equals() untuk objek String yang direferensi oleh string1 dan melewatkan string3 sebagai argumennya. Metode equals() melakukan perbandingan case-sensitive (membedakan huruf besar dari huruf kecil ekivalennya) dan menghasilkan true jika kedua string sama dan false jika sebaliknya. Kedua string sama jika keduanya memiliki panjang sama, atau memiliki banyak karakter yang sama, dan tiap karakter pada satu string identik dengan karakter terkait pada string lain.

Tentu, Anda dapat menggunakan metode equals() untuk string yang direferensi oleh string3 untuk melakukan perbandingan:

if(string3.equals(string1)) {
   System.out.println(“string3.equals(string1) bernilai true. “ +
       “ jadi kedua string sama.”);
}

Ini sama efektifnya dengan versi sebelumnya.

Untuk memeriksa ekualitas antara dua string dengan mengabaikan perbedaan antara huruf besar dari huruf kecil ekivalennya, Anda menggunakan metode equalsIgnoreCase().

Latihan
Identitas String
Lakukan perubahan pada BandingString.java dari contoh sebelumnya:

public class BandingString2 {
   public static void main(String[] args) {
      String string1 = "Terlalu banyak ";
      String string2 = "pendapat";
      String string3 = "Terlalu banyak pendapat";

      // Membuat string1 dan string3 mereferensi ke string berbeda
      // yang identik
      string1 += string2;

      // Menampilkan isi dari string-string
      System.out.println("Uji 1");
      System.out.println("string3 sekarang adalah: " + string3);
      System.out.println("string1 sekarang adalah: " + string1);

      if(string1.equals(string3)) { // Sekarang uji ekualitas
         System.out.println("string1.equals(string3) bernilai true." +
            " string1 dan string3 sama");
      } else {
         System.out.println("string1.equals(string3) bernilai false." +
            " string1 dan string3 tidak sama");
      }
     
      // Sekarang buat string1 dan string2 mereferensi ke string berbeda
      // dengan huruf besar tertentu
      string3 = "TERLALU banyak pendapat";
     
      // Menampilkan isi dari string-string
      System.out.println("\n\nUji 2");
      System.out.println("string3 sekarang adalah: " + string3);
      System.out.println("string1 sekarang adalah: " + string1);
      
      if(string1.equals(string3)) { // Sekarang uji ekualitas
         System.out.println("string1.equals(string3) bernilai true." +
            " string1 dan string3  sama");
      } else {
         System.out.println("string1.equals(string3) bernilai false." +
            " string1 dan string3 tidak sama");
      }
     
      if(string1.equalsIgnoreCase(string3)) { // Sekarang uji identitas
         System.out.println("string1.equalsIgnoreCase(string3) bernilai true." +
            " string1 dan string3 sama (dengan mengabaikan sensitifitas huruf)");
      } else {
         System.out.println("string1.equalsIgnoreCase(string3) bernilai false." +
            " string1 dan string3 tidak sama");
      }     
     
   }
}

Keluaran program:

Uji 1
string3 sekarang adalah: Terlalu banyak pendapat
string1 sekarang adalah: Terlalu banyak pendapat
string1.equals(string3) bernilai true. string1 dan string3 sama


Uji 2
string3 sekarang adalah: TERLALU banyak pendapat
string1 sekarang adalah: Terlalu banyak pendapat
string1.equals(string3) bernilai false. string1 dan string3 tidak sama
string1.equalsIgnoreCase(string3) bernilai true. string1 dan string3 sama
(dengan mengabaikan sensitifitas huruf)

Penjelasan
Pada ekspresi if, Anda memanggil metode equals() untuk objek string1 untuk menguji ekualitasnya dengan string3. Ini adalah sintaksis yang Anda telah gunakan untuk memanggil metode println() dari objek out. Secara umum, untuk memanggil sebuah metode dari objek tertentu, Anda menuliskan nama objek, kemudian tanda-titik, dan kemudian nama metode. Tandar-kurung yang ada setelah nama metode mengapit informasi yang akan dilewatkan kepada metode, pada kasus ini string3. Bentuk umum dari pemanggilan metode dari objek tertentu ditunjukkan pada Gambar 4-10.

Gambar 4-10

Metode equals() memerlukan satu argumen yang Anda tempatkan ke dalam kurung. Argumen tersebut harus berupa objek String yang akan dibandingkan dengan objek semula (pemilik metode equals(), pada kasus ini objek string1). Seperti yang Anda lihat sebelumnya, metode ini menghasilkan true jika string yang dilewatkan (string3 pada kasus ini) identik dengan string yang ditunjuk oleh objek String pemilik metode.

Baris berikutnya pada kode program setelah menampilkan nilai dari string3 dan string1 adalah:

if(string1.equals(string3)) { // Sekarang uji ekualitas
   System.out.println("string1.equals(string3) bernilai true." +
      " string1 dan string3 sama");
} else {
   System.out.println("string1.equals(string3) bernilai false." +
      " string1 dan string3 tidak sama");
}

Keluaran dari statemen ini menunjukkan bahwa pemanggilan metode equals() untuk string1 dan string3 sebagai argumennya menghasilkan true. Anda membuat string3 mereferensi sebuah string baru. Anda kemudian membandingkan nilai dari string1 dan string3 sekali lagi, dan hasil perbandingan sekarang bernilai false.

Terakhir, Anda membandingkan string1 dan string3 menggunakan metode equalsIgnoreCase(). Di sini hasilnya adalah true karena kedua string hanya berbeda pada sensitifitas huruf dari tiga karakter pertama.


Memeriksa Awal da Akhir String
Kadangkala, ada gunanya untuk memeriksa sebagian dari sebuah string. Anda dapat menguji apakah sebuah string diawali runtun karakter tertentu menggunakan metode startsWith() untuk objek String. Argumen untuk metode ini adalah string yang akan diuji. String argumen dapat memiliki panjang berapapun. Jika string1 telah didefinisikan sebagai “Terlalu banyak pendapat”, maka ekspresi string1.startsWith(“Terlalu”) akan memiliki nilai true. Begitu pula dengan ekspresi string1.startsWith(“Terlalu ban”).

Berikut adalah salah satu contoh penggunaan metode ini:

String string1 = “Terlalu banyak pendapat”;
if(string1.startsWith(“Terlalu”)) {
   System.out.println(“String diawali dengan \”Terlalu\”!”);
}

Perbandingan berwatak case-sensitive, dimana huruf besar berbeda dari huruf kecil ekivalen. Jadi, ekspresi string1.startsWith(“terlalu”) akan menghasilkan nilai false.

Metode komplementer endsWith() memeriksa apa yang ada di akhir dari sebuah string, jadi ekspresi string1.endsWith(“pendapat”) akan menghasilkan nilai true. Perbandingan dengan metode ini juga berwatak case-sensitive.


Mengurutkan String
Anda dapat mengurutkan string-string ketika Anda memiliki sebuah koleksi nama. Pengujian ekualitas tidak banyak menolong karena untuk mengurutkan string-string Anda perlu menentukan apakah satu string lebih besar dari atau sama dengan string lain. Apa yang Anda perlukan adalah metode compareTo() pada kelas String. Metode ini membandingkan objek String pemanggil dengan argumen String yang dilewatkan kepada metode compareTo(). Metode ini menghasilkan sebuah integer negatif jika objek String pemanggil bernilai lebih kecil dari argumen yang dilewatkan, menghasilkan nol jika objek String bernilai sama dengan argumen, dan menghasilkan integer positif jika objek String bernilai lebih besar dari argumen. Tentu, pengurutan string memerlukan definisi jelas atas apa itu istilah lebih kecil dari, sama dengan, dan lebih besar dari.

Metode compareTo() membandingkan dua string dengan membandingkan karakter-karakter secara berurutan, diawali dari karakter pertama pada tiap string. Proses berlanjut sampai dijumpai karakter berbeda pada kedua string atau sampai perbandingan terhadap karakter terakhir pada salah satu atau kedua string selesai dilakukan. Karakter-karakter dibandingkan dengan membandingkan kode-kode Unicodenya. Jadi, dua karakter bernilai sama jika nilai numerik dari representasi Unicodenya bernilai sama. Satu karakter lebih besar dari karakter lain jika nilai numerik dari representasi Unicodenya bernilai lebih besar dari representasi Unicode dari karakter lain. Satu karakter lebih kecil dari karakter lain jika nilai numerik dari representasi Unicodenya bernilai lebih kecil dari representasi Unicode dari karakter lain.


Latihan
Loop for Numerik
Pada contoh ini, Anda akan menciptakan tiga string yang dapat dibandingkan menggunakan metode compareTo(). Ketikkan kode berikut:

public class UrutString {
   public static void main(String[] args) {
      // String-string yang akan dibandingkan
      String string1 = "A";
      String string2 = "S";
      String string3 = "Z";

      // String-string untuk ditampilkan
      String string1Out = "\"" + string1 + "\""; // string1 dengan kutip
      String string2Out = "\"" + string2 + "\""; // string2 dengan kutip
      String string3Out = "\"" + string3 + "\""; // string3 dengan kutip

      // Membandingkan string1 dengan string3
      if(string1.compareTo(string3) < 0) {
         System.out.println(string1Out + " lebih kecil dari " + string3Out);
      } else {
         if(string1.compareTo(string3) > 0) {
            System.out.println(string1Out + " lebih besar dari " + string3Out);
         } else {
            System.out.println(string1Out + " sama dengan " + string3Out);
         }
      }

      // Membandingkan string2 dengan string1
      if(string2.compareTo(string1) < 0) {
         System.out.println(string2Out + " lebih kecil dari " + string1Out);
      } else {
         if(string2.compareTo(string1) > 0) {
            System.out.println(string2Out + " lebih besar dari " + string1Out);
         } else {
            System.out.println(string2Out + " sama dengan " + string1Out);
         }
      }
   }
}

Keluaran program:

"A" lebih kecil dari "Z"
"S" lebih besar dari "A"

Penjelasan
Anda seharusnya tidak mengalami kesulitan memahami contoh ini. Anda mendeklarasikan dan menginisialisasi ketiga variabel String: string1, string2, dan string3. Anda kemudian menciptakan tiga variabel String lain yang berkaitan dengan tiga string pertama tetapi dengan karakter kutip-ganda di awal dan di akhirnya. Ini berguna untuk menyederhanakan statemen keluaran. Anda kemudian memiliki sebuah statemen if dengan sebuah statemen if bersarang untuk membandingkan string1 dengan string3:

// Membandingkan string1 dengan string3
if(string1.compareTo(string3) < 0) {
   System.out.println(string1Out + " lebih kecil dari " + string3Out);
} else {
   if(string1.compareTo(string3) > 0) {
      System.out.println(string1Out + " lebih besar dari " + string3Out);
   } else {
      System.out.println(string1Out + " sama dengan " + string3Out);
   }
}

Statemen if sebelah-luar menentukan apakah string1 bernilai lebih kecil dari string3. Jika ya, sebuah pesan akan ditampilkan. Jika string1 tidak lebih kecil dari string3, maka kedua string bisa jadi bernilai sama atau string1 bernilai lebih besar dari string3. Statemen if sebelah-dalam memutuskannya.

Anda membandingkan string2 dengan string1 dengan cara sama. Seperti pada metode equals(), argumen pada metode compareTo() dapat berupa sembarang ekspresi yang menghasilkan sebuah objek String.


Mengakses Karakter-Karakter Pada String
Ketika Anda memproses string, cepat atau lambat Anda akan membutuhkan cara untuk mengakses karakter-karakter individual pada sebuah objek String. Untuk mengakses karakter tertentu pada posisi tertentu dalam sebuah string, Anda menggunakan sebuah indeks bertipe int yang menjadi offset dari posisi karakter dari awal string.

Prinsipnya sama persis dengan pengaksesan elemen array. Karakter pertama pada sebuah string berada pada posisi 0, karakter kedua pada posisi 1, karakter ketiga pada posisi 2, dan seterusnya. Namun, meskipun prinsipnya sama, praktenya berbeda. Anda tidak bisa menggunakan kurung-sikut untuk mengakses karakter-karakter pada sebuah string, Anda harus menggunakan metode.


Mengekstraksi Karakter-Karakter String
Anda dapat mengekstraksi sebuah karakter dari suatu objek String menggunakan metode charAt(). Metode ini menerima sebuah argumen integer yang menjadi indeks posisi karakter dari awal string. Jika Anda mencoba menggunakan sebuah indeks yang lebih kecil dari 0 atau lebih besar dari indeks untuk posisi terakhir pada string, maka Anda akan menyebabkan sebuah eksepsi dilemparkan, yang menyebabkan program terhenti. Tentang eksepsi akan dijelaskan nanti pada Bab 7. Untuk sementara ini, Anda hanya perlu mengetahui bahwa tipe eksepsi yang dilemparkan pada kasus ini adalah StringIndexOutOfBoundsException.

Untuk menghindari error jenis ini, Anda hanya perlu menentukan panjang dari objek String. Untuk mendapatkan panjang string, Anda perlu memanggil metode length() dari objek tersebut. Perhatikan perbedaan antara cara ini dengan cara Anda mendapatkan panjang array. Di sini, Anda memanggil metode length() dari sebuah objek String, sedangkan pada array Anda mengakses anggota datanya, length. Anda dapat mengeksplorasi penggunaan charAt() dan metode length() pada kelas String pada contoh berikut.


Latihan
Mengekstraksi Karakter-Karakter Pada Sebuah String
Pada kode berikut, sebuah string yang cukup panjang akan dianalisa karakter-demi-karakter untuk menentukan banyak huruf vokal, spasi, dan huruf konsonan yang ada di dalamnya.

public class KarakterString {
   public static void main(String[] args) {
      // String teks yang akan dianalisa
      String teks = "Pada rezim ini, sangat banyak orang diciduk,"
                    +" hanya karena cuitan yang impulsif dan emosional"
                    +" sesaat, mereka harus mendekam di dalam penjara."
                    +" Kebebasan berekspresi sudah dipasung, atau karena"
                    +" pengguna kebebasan itu yang kurang bertanggung-jawab?";

      int spasi = 0, // Banyak karakter spasi
          vokal = 0, // Banyak huruf vokal
          huruf = 0; // Banyak huruf
         
      // Mengenalisa semua karakter pada string
      int panjangTeks = teks.length(); // Mendapatkan panjang string

      for(int i = 0; i < panjangTeks; i++) {
         // Memeriksa vokal
         char ch = Character.toLowerCase(teks.charAt(i));
         if(ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') {
            vokal++;
         }
        
         //Memeriksa huruf
         if(Character.isLetter(ch)) {
            huruf++;
         }
        
         // Memeriksa spasi
         if(Character.isWhitespace(ch)) {
            spasi++;
         }
      }
     
      System.out.println("Teks memuat vokal: " + vokal + "\n" +
         " konsonan: " + (huruf-vokal) + "\n"+
         " spasi: " + spasi);
   }
}

Keluaran program:

Teks memuat vokal: 86
konsonan: 119
spasi: 32

Penjelasan
Variab String, teks, diinisialisasi dengan kalimat seperti pada program. Semua penghitungan karakter dilakukan pada loop for, yang dikendalikan oleh indeks i. Loop tetap dieksekusi sepanjang i bernilai kurang dari panjang string, yang dihasilkan oleh metode teks.length(), yang hasilnya Anda simpan pada variabel panjangTeks.

Dimulai dengan karakter pertama, yang memiliki nilai indeks 0, Anda mengekstraksi tiap karakter dari string dengan memanggil metode charAt(). Anda menggunakan indeks loop i sebagai indeks dari posisi karakter pada string. Metode ini menghasilkan karakter pada posisi i sebagai sebuah nilai bertipe char, dan Anda kemudian mengkonversinya menjadi huruf kecil dengan memanggil metode static pada kelas Character, toLowerCase(). Karakter yang akan dikonversi dilewatkan sebagai argumen, dan metode ini menghasilkan huruf kecil ekivalen dari argumennya.

Ini adalah cara alternatif dalam menggunakan metode toLowerCase() pada kelas Character. Kelas String juga memuat sebuah metode toLowerCase() yang akan mengkonversi keseluruhan string menjadi huruf kecil dan menghasilkan sebuah referensi yang menunjuk ke string terkonversi. Anda dapat mengkonversi string teks menjadi semua huruf kecil dengan statemen berikut:

teks = teks.toLowerCase(); // Konversi string menjadi semua huruf kecil

Statemen ini mengganti string semula dengan semua huruf kecil ekivalennya. Jika Anda ingin mendapatkan kembali string semula, Anda dapat menyimpan referensi ke string huruf kecil pada variabel lain yang bertipe String. Kelas String juga mendefinisikan metode toUpperCase() untuk mengkonversi sebuah string menjadi semua huruf besar, yang bisa Anda gunakan dengan cara sama seperti metode toLowerCase().

Ekspresi if memeriksa ada tidaknya huruf vokal dengan melakukan peng-OR-an perbandingan dengan lima karakter vokal. Jika ekspresi ini bernilai true, maka Anda menginkremen cacah vokal. Untuk memeriksa ada tidaknya huruf pada sebuah string, Anda menggunkaan metode isLetter() pada kelas Character, dan mengakumulasi cacah huruf total pada variabel huruf. Dengan mengetahui banyak total huruf, Anda bisa mendapatkan banyak total huruf konsonan dengan mengurangkan banyak huruf vokal dari banyak total huruf. Terakhir, kode loop memeriksa ada tidak karakter spasi menggunakan metode isWhitespace() pada kelas Character. Metode ini menghasilkan true jika karakter yang dilewatkan sebagai argumen adalah sebuah karakter spasi-putih Unicode.


Melakukan Pencarian Karakter Pada String
Ada dua metode yang tersedia bagi Anda pada kelas String yang dapat melakukan pencarian karakter pada sebuah string: indexOf() dan lastIndexOf(). Tiap metode ini memiliki empat varian. Pilihan dasarnya adalah ketika Anda ingin melakukan pencarian karakter tunggal atau sebuah substring pada sebuah string.

Untuk melakukan pencarian karakter tunggal, ‘a’ misalnya, pada sebuah string teks, Anda bisa menuliskan:

int indeks = 0;                   // Posisi dari karakter pada string
indeks = teks.indexOf(‘a’); // Mencari posisi indeks pertama yang memuat ‘a’


Metode indexOf() akan melakukan pencarian pada isi string teks dimulai dari awal string dan menghasilkan posisi indeks dari kemunculan pertama dari karakter ‘a’. Jika ‘a’ tidak ditemukan, metode ini akan menghasilkan nilai -1.







No comments: