Array merupakan jenis struktur data yang sangat dasar dan sangat penting. Teknik pengolahan array merupakan teknik pemrograman yang paling penting yang kita harus kuasai. Dua jenis teknik pengolahan array -- pencarian dan pengurutan -- akan dibahas kemudian. Bagian ini akan memperkenalkan beberapa ide dasar pengolahan array secara umum.
Dalam banyak hal, pengolahan array berarti menggunakan operasi yang sama kepada setiap elemen di dalam array. Biasanya sering dilakukan dengan perulangan for. Perulangan untuk mengolah semua elemen dalam array A dapat ditulis dalam bentuk :
// lakukan inisialiasi yang diperlukan sebelumnya for (int i = 0; i < A.length; i++) { . . . // proses A[i] }
Mulai dengan 0; Tambah A[0]; (proses elemen pertama di dalam A) Tambah A[1]; (proses elemen kedua di dalam A) . . . Tambah A[ A.length - 1 ]; (proses elemen terakhir di dalam A)
double jumlah; // Jumlah nilai di dalam A jumlah = 0; // Mulai dengan 0 for (int i = 0; i < A.length; i++) jumlah += A[i]; // tambah A[i] ke dalam jumlah untuk i = 0, 1, ..., A.length - 1
Lihat bahwa kondisi kelanjutan "i < A.length" menyatakan bahwa nilai i terakhir yang akan diolah adalah A.length - 1 yaitu elemen terakhir dalam array. Ingat bahwa kita menggunakan "<" bukan "<=" karena dengan "<=" komputer akan memberikan kesalahan indeks di luar batas.
Pada akhirnya, nanti Anda akan bisa membuat perulangan seperti di atas di luar kepala. Kita akan lihat beberapa contohnya. Di sini perulangan akan menghitung banyaknya elemen di dalam array A yang nilainya kurang dari nol :
int hitung; // Untuk menghitung elemen hitung = 0; // Mulai dengan nol for (int i = 0; i < A.length; i++) { if (A[i] < 0.0) // Jika elemen ini kurang dari nol hitung++; // tambah hitung dengan 1 } // Di sini nilai "hitung" adalah banyaknya elemen yang kurang dari 0.
int hitung = 0; // lihat kondisi for berubah dibandingkan dengan contoh sebelumnya for (int i = 0; i < A.length - 1; i++) { if (A[i] == A[i+1]) hitung++; }
double maks = A[0]; // nilai maks berisi elemen array pertama for (int i = 1; i < A.length; i++) { // i mulai dari elemen kedua if (A[i] > maks) max = A[i]; } // Di sini maks berisi nilai elemen array yang paling besar
(Ada masalah yang lebih penting di sini. Java membolehkan array memiliki panjang nol. Artinya bahkan A[0] pun tidak ada di dalam array, sehingga memanggil A[0] akan menghasilkan kesalahan indeks keluar batas. Akan tetapi array biasanya array dengan panjang nol biasanya sesuatu yang kita ingin hindarkan dalam kehidupan sehari-hari. Lagian apa artinya mencari nilai terbesar di dalam suatu array yang panjangnya nol?)
Contoh terakhir dari operasi array, misalnya kita ingin mengkopi suatu array. Untuk mengkopi array A, tidak cukup untuk menggunakan perintah
double[] B = A;
// Buat objek array baru, yang panjangnya sama dengan panjang A double[] B = new double[A.length]; for (int i = 0; i < A.length; i++) B[i] = A[i]; // Kopi setiap elemen dari A ke B
public static void arraycopy(Object arraySumber, int indeksAwalSumber, Object arrayTujuan, int indeksAwalTujuan, int jumlah)
di mana arraySumber dan arrayTujuan bisa berbentuk array dengan tipe apapun. Nilai akan dikopi dari arraySumber kearrayTujuan. jumlah adalah berapa banyak elemen yang akan dikopi. Nilai akan dikopi dari arraySumber mulai dari posisiindeksAwalSumber dan akan disimpan pada arrayTujuan mulai dari posisi indeksAwalTujuan. Misalnya kita akan mengkopi array A, maka kita bisa menggunakan perintah
double B = new double[A.length]; System.arraycopy( A, 0, B, 0, A.length );
Suatu tipe array, misalnya double[ ] adalah tipe Java biasa, sehingga kita bisa menggunakannya seperti tipe-tipe Java lainnya. Termasuk juga digunakan sebagai parameter formal di dalam suatu subrutin. Juga bisa digunakan sebagai tipe keluaran suatu fungsi. Misalnya, 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, maka kembalikan null if ( sumber == null ) return null; double[] kpi; // Kopi array sumber kpi = new double[sumber.length]; System.arraycopy( sumber, 0, kpi, 0, sumber.length ); return kpi; }
Rutin main() memiliki parameter dengan tipe String[] yang merupakan array String. Ketika sistem memanggil rutin main(), string di dalam array ini adalah parameter dari baris perintah. Jika kita menggunakan konsol, user harus mengetikkan perintah untuk menjalankan program. User bisa menambahkan input tambahan dalam perintah ini setelah nama program yang akan dijalankan.
Misalnya, jika kelas yang memiliki rutin main() bernama programKu, maka user bisa menjalankan kelas tersebut dengan perintah "java programKu" di konsol. Jika kita tulis dengan "java programKu satu dua tiga", maka parameter dari baris perintahnya adalah "satu", "dua", dan "tiga". Sistem akan memasukkan parameter-parameter ini ke dalam array String[] dan memberikan array ini pada rutin main().
Berikut ini adalah contoh program sederhana yang hanya mencetak parameter dari baris perintah yang dimasukkan oleh user.
public class CLDemo { public static void main(String[] args) { System.out.println("Anda memasukkan " + args.length + " parameter dari baris perintah"); if (args.length > 0) { System.out.println("Parameter tersebut adaah :"); for (int i = 0; i < args.length; i++) System.out.println(" " + args[i]); } } // akhir main() } // akhir kelas CLDemo
Hingga sekarang, contoh yang telah diberikan adalah bagaimana mengolah array dengan mengakses elemennya secara berurutan (sequential access). Artinya elemen-elemen array diproses satu per satu dalam urutan dari awal hingga akhir. Akan tetapi salah satu keuntungan array adalah bahwa array bisa digunakan untuk mengakses elemennya secara acak, yaitu setiap elemen bisa diakses kapan saja secara langsung.
Misalnya, kita ambil contoh suatu masalah yang disebut dengan masalah ulang tahun: Misalnya ada N orang di dalam suatu ruangan. Berapa kemungkinan dua orang di dalam ruangan tersebut memiliki ulang tahun yang sama (yang dilahirkan pada tanggal dan bulan yang sama, meskipun tahunnya berbeda)? Kebanyakan orang salah menerka jawabannya. Sekarang kita lihat dengan versi masalah yang berbeda: Misalnya kita memilih orang secara acak dan menanyakan ulang tahunnya. 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, akan tetapi kita bisa simulasikan dengan program komputer dan menjalankan beberapa kali hingga kita tahu berapa kira-kira orang harus dicek.
Untuk mensimulasikan percobaan ini, kita harus mencatat semua ulang tahun yang kita sudah tanyakan. Ada 365 kemungkinan hari ulang tahun (Kita abaikan sementara tahun kabisat). Untuk setiap kemungkinan hari ulang tahun, kita perlu tahu, apakah hari ulang tahun tersebut telah digunakan? Jawabannya adalah nilai boolean true atau false. Untuk menyimpan data ini, kita bisa gunakan array dari 365 nilai boolean:
boolean[] sudahDitanya; sudahDitanya = new boolean[365];
Tanggal-tanggal pada satu tahun dinomori dari 0 hingga 364. Nilai sudahDitanya[i] akan bernilai true jika orang yang kita tanya berulang tahun pada hari tersebut. Pada awalnya semua nilai pada array sudahDitanya[i] bernilai false. Ketika kita memilih satu orang dan menanyakan hari ulang tahunnya, misalnya i, kita akan mengecek terlebih dahulu apakah sudahDitanya[i] bernilai true. Jika tidak maka orang ini adalah orang kedua dengan ulang tahun yang sama. Artinya kita sudah selesai.
Jika sudahDitanya[i] bernilai false, maka belum ada orang sebelum ini yang memiliki hari ulang tahun tersebut. Kita akan gantisudahDitanya[i] dengan true, kemudian kita akan tanyakan lagi kepada orang lain, dan begitu seterusnya hingga semua orang di dalam ruangan ditanyakan.
static void masalahUlangTahun() { // Melakukan simulasi dengan memilih seseorang secara acak // dan mengecek hari ulang tahunnya. Jika hari ulang tahunnya // sama dengan orang yang pernah kita tanya sebelumnya, // hentikan program dan laporkan berapa orang yang sudah dicek boolean[] sudahDitanya; // 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; // Jumlah orang yang sudah pernah ditanya sudahDitanya = new boolean[365]; // Awalnya, semua nilai adalah false hitung = 0; while (true) { // Ambil ulang tahun secara acak dari 0 hingga 364 // Jika ulang tahun telah ditanya sebelumnya, keluar // Jika tidak catat dalam array int ultah; // Ulang tahun seseorang ultah = (int)(Math.random()*365); hitung++; if ( sudahDitanya[ultah] ) break; sudahDitanya[ultah] = true; } System.out.println("Ulang tahun yang sama ditemukan setelah menanyakan " + hitung + " orang."); } // akhir masalahUlangTahun()
for (int i = 0; i < 365; i++) sudahDitanya[i] = false;
Array paralel adalah menggunakan beberapa array dengan indeks yang sama. Misalnya kita ingin membuat beberapa kolom secara paralel -- array x di kolom pertama, array y di kolom kedua, array warna di kolom ketiga, dan seterusnya. Data untuk baris ke-i bisa didapatkan dari masing-masing array ini. 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. Jika kita mengikuti aturan seperti ini, amaka kita tidak harus membayangkan hubungan data yang satu dan yang lainnya karena semua data akan dikelompokkan di dalam satu tempat.
Misalnya saya menulis kelas seperti
class DataString { // Data dari salah satu pesan int x,y; // Posisi pesan Color warna; // Warna pesan }
DataString[] data;
data = new DataString[JUMLAH_PESAN];
Setelah array ini dibuat, nilai setiap elemen array adalah null. Kita ingin menyimpan data di dalam objek yang bertipeDataString, akan tetapi tidak ada objek yang dibuat. Yang kita sudah buat hanyalah kontainernya saja. Elemen di dalamnya berupa objek yang belum pernah kita buat. Untuk itu elemen di dalamnya bisa kita buat dengan perulangan for seperti :
for (int i = 0; i < JUMLAH_PESAN; i++) data[i] = new DataString();
switch (bulan) { case 0: bulanString = "Januari"; break; case 1: bulanString = "Februari"; break; case 2: bulanString = "Maret"; break; case 3: bulanString = "April"; break; . . . case 11: bulanString = "Desember"; break; default: bulanString = "Salah bulan"; }
static String[] namaBulan = { "Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember" };
bulanString = namaBulan[bulan];
bagaimana cara menampilkan bilangan terbesar ke terkecil
BalasHapus