Showing posts with label belajar array. Show all posts
Showing posts with label belajar array. Show all posts

Monday

Array Multi Dimensi

Tipe apapun bisa digunakan sebagai tipe dasar suatu array. Kita bisa membuat array int, array String, array Object dan seterusnya. Terutama, karena array adalah tipe Java kelas satu, kita bisa membuat array yang bertipe array.
Misalnya suatu array bertipe int[], juga otomatis memiliki array bertipe int[][], yaitu "array bertipe array int". Array tersebut disebut array 2 dimensi. Tentunya, dengan tipe int[][], kita juag bisa membuat arraynya dengan tipe int[][][], yang merupakan array 3 dimensi, dan seterusnya. Tidak ada batasan berapa dimensi array yang kita buat, akan tetapi bukan sesuatu yang biasa dilakukan untuk membuat array lebih dari 3 dimensi. Pembahasan kita akan lebih dikhususkan pada array 2 dimensi. Tipe TipeDasar[][] biasanya dibaca "array 2 dimensi bertipe TipeDasar" atau "array dari array TipeDasar".
Deklarasi pernyataan "int[][] A;" adalah membuat variabel bernama A dengan tipe int[][]. Variabel ini berisi objek yang bertipe int[][]. Pernyataan pemberian nilai "A = new int[3][4];" akan membuat objek array 2 dimensi dan mengisi A ke objek yang baru dibuat tersebut.
Seperti biasa, deklarasi dan pemberian nilai bisa digabung menjadi satu pernyataan, seperti "int[][] A = new int[3][4];". Objek yang baru dibuat adalah objek yang merupakan array dari array int. Bagian int[3][4] menyatakan bahwa ada 3 array int di dalam array A, dan di setiap array int tersebut terdapat 4 int.
Cara seperti itu mungkin sedikit membingungkan, akan tetapi akan lebih mudah apabila kita bayangkan array tersebut seperti matriks. Istilah "int[3][4]" bisa disebut sebagai matriks dengan 3 baris dan 4 kolom, seperti pada ilustrasi berikut ini :

Untuk banyak hal, kita bisa mengabaikan kenyataan di atas, dan membayangkan bentuk matriks seperti di atas. Kadang-kadang kita juga harus ingat bahwa setiap baris sebenarnya juga merupakan suatu array. Array-array ini bisa dirujuk dengan A[0], A[1], dan A[2]. Setiap baris bertipe int[].
Pernyataan A[1] merujuk pada salah satu baris pada array A. Karena A[1] itu sendiri sebenarnya adalah array int, kita bisa menambah indeks lain untuk merujuk pada posisi pada baris tersebut. Misalnya A[1][3] adalah elemen nomor 3 pada baris 1. Seperti biasa, ingat bahwa posisi baris dan kolom dimulai dari 0. Jadi pada contoh di atas, A[1][3] bernilai 5. Lebih umum lagi, A[i][j] adalah posisi pada baris i dan kolom j. Seluruh elemen pada A bisa dinamakan seperti berikut :
A[0][0]    A[0][1]     A[0][2]     A[0][3]
A[1][0]    A[1][1]     A[1][2]     A[1][3]
A[2][0]    A[2][1]     A[2][2]     A[2][3]
A[i][j] adalah variabel bertipe int. Kita bisa mengisi nilainya atau menggunakannya seperti variabel bertipe int biasa.
Perlu juga diketahui bahwa A.length akan memberikan jumlah baris pada A. Untuk mendapatkan jumlah kolom pada A, kita harus mencari jumlah int dalam setiap baris, yaitu yang disimpan pada A[0]. Jumlah kolom ini bisa didapatkan dengan menggunakan A[0].length, atau A[1].length atau A[2].length. (Tidak ada aturan baku yang menyatakan bahwa pada setiap baris suatu array harus memiliki panjang yang sama, dan sebenarnya pada beberapa aplikasi, juga digunakan array dengan panjang yang berbeda-beda pada setiap barisnya. Akan tetapi apabila kita membuat array dengan perintah seperti di atas, maka kita akan selalu mendapatkan array dengan panjang array yang sama.)
Array 3 dimensi juga dibuat dan diolah dengan cara yang sama. Misalnya, array 3 dimensi bertipe int bisa dibuat dengan pernyataan "int[][][] B = new int [7][5][11];". Kita juga bisa mengilustrasikannya sebagai kubus 3-dimensi. Masing-masing bloknya bertipe int yang bisa dipanggil dalam bentuk B[i][j][k]. Array dimensi lain yang lebih tinggi juga mengikuti pola yang sama, akan tetapi akan sangat sulit untuk membuat visualisasi struktur arraynya.

Kita bisa mengisi array multi dimensi sekaligus pada saat dideklarasikan. Ingat sebelumnya bagaimana array 1 dimensi biasa dideklarasikan, dan bagaimana isinya diinisialisasikan, yaitu seperti daftar nilai-nilainya yang dipisahkan dengan koma, dan diletakkan di dalam tanda kurung kurawal { dan }.
Inisialisasi array bisa juga digunakan untuk array multi dimensi, yang terdiri dari beberapa inisialisasi array 1 dimensi, masing-masing untuk setiap barisnya. Misalnya, array A pada gambar di atas dapat dibuat dengan perintah :
int[][] A = { {  1,  0, 12, -1 },
              {  7, -3,  2,  5 },
              { -5, -2,  2,  9 }
};
Jika tidak ada inisialisasi yang diberikan untuk suatu array, maka nilainya akan diisi dengan nilai awal tergantung pada tipenya : nol untuk bilangan, false untuk boolean dan null untuk objek.

Seperti halnya array 1 dimensi, array 2 dimensi juga sering diolah dengan menggunakan perulangan for. UNtuk mengolah semua elemen pada array 2 dimensi, kita bisa menggunakan pernyataan for bertingkat. Jika array A dideklarasikan seperti
int[][]  A  =  new int[3][4];
maka kita bisa mengisi 0 untuk semua elemen pada A dengan menggunakan
for (int baris = 0;  baris < 3;  baris++) {
    for (int kolom = 0;  kolom < 4;  kolom++) {
        A[baris][kolom] = 0;
    }
}
Pertama kali perulangan for bagian luar akan memproses dengan baris = 0. Bagian dalamnya akan mengisi keempat kolom pada baris pertama, yaitu A[0][0] = 0, A[0][1] = 0, A[0][2] = 0, dan A[0][3] = 0. Kemudian perulangan for bagian luar akan mengisi baris kedua, dan seterusnya.
Dan juga, kita bisa menjumlah semua elemen pada A dengan
int jml = 0;
for (int i = 0; i < 3; i++)
    for (int j = 0; j < 4; i++)
        jml = jml + A[i][j];
Untuk mengolah array 3 dimensi, tentunya kita harus menggunakan perulangan for bertingkat 3.

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

Sunday

Array Dinamis

Panjang suatu array tidak bisa diubah setelah dibuat. Akan tetapi, sering kali jumlah data yang disimpan dalam array bisa berubah setiap saat. Misalnya dalam contoh berikut : Suatu array menyimpan baris teks dalam program pengolah kata. Atau suatu array yang menyimpan daftar komputer yang sedang mengakses halaman suatu website. Atau array yang berisi gambar yang ditambahkan user oleh program gambar. Di sini jelas, bahwa kita butuh sesuatu yang bisa menyimpan data di mana jumlahnya tidak tetap.

Array Setengah Penuh
Bayangkan suatu aplikasi di mana sejumlah item yang ingin kita simpan di dalam array akan berubah-ubah sepanjang program tersebut berjalan. Karena ukuran array tidak bisa diubah, maka variabel terpisah digunakan untuk menyimpan berapa banyak sisa tempat kosong yang masih bisa diisi di dalam array.
Bayangkan misalnya, suatu program yang membaca bilangan bulat positif dari user, kemudian menyimpannya untuk diproses kemudian. Program akan berhenti membaca input apabila input yang diterima bernilai 0 atau kurang dari nol. Bilangan input n tersebut kita simpa di dalam array bilangan dengan tipe int[]. Katakan banyaknya bilangan yang bisa disimpan tidak lebih dari 100 buah. Maka ukuran array bisa dibuat 100.
Akan tetapi program tersebut harus melacak berapa banyak bilangan yang sudah diambil dari user. Kita gunakan variabel terpisah bernama jmlBilangan. Setiap kali suatu bilangan disimpan di dalam array, nilai jmlBilangan akan bertambah satu.
Sebagai contoh sederhana, masi kita buat program yang mengambil bilangan yang diinput dari user, kemudian mencetak bilangan-bilangan tersebut dalam urutan terbalik. (Ini adalah contoh pengolahan yang membutuhkan array, karena semua bilangan harus disimpan pada suatu tempat. Banyak lagi contoh program misalnya, mencari jumlah atau rata-rata atau nilai maksimum beberapa bilangan, bisa dilakukan tanpa menyimpan bilangan tersebut satu per satu)

public class BalikBilanganInput {
 
    public static void main(String[] args) {
 
        int[] bilangan;  // Array untuk menyimpan nilai input dari user
        int jmlBilangan;    // Banyaknya bilangan yang sudah disimpan dalam array
        int bil;          // Bilangan yang diambil dari user
 
        bilangan = new int[100];   // Buat array dengan 100 bilangan int
        jmlBilangan = 0;                // Belum ada bilangan yang disimpan
 
        System.out.println("Masukkan bilangan bulat positif (paling banyak 100 bilangan)" + 
            ", masukkan nol untuk mengakhiri.");
 
        while (true) {
            System.out.print("? ");
            bil = KonsolIO.ambilInt();
            if (bil <= 0)
                break;
            bilangan[jmlBilangan] = bil;
            jmlBilangan++;
        }
 
        System.out.println("\nBilangan yang Anda masukkan dalam urutan terbalik adalah :\n");
 
        for (int i = jmlBilangan - 1; i >= 0; i--) {
            System.out.println( bilangan[i] );
        }
 
    } // akhir main();
 
}  // akhir kelas BalikBilanganInput 
Penting untuk diingat bahwa jmlBilangan memiliki dua peran. Yang pertama, adalah melacak banyaknya bilangan yang sudah dimasukkan di dalam array. Yang kedua adalah menentukan di mana indeks kosong berikutnya di dalam array. Misalnya, jika 4 bilangan sudah dimasukkan ke dalam array, maka bilangan-bilangan tersebut diisi pada array di posisi 0, 1, 2, dan 3. Maka posisi kosong berikutnya adalah posisi 4.
Ketika kita akan mencetak angka di dalam array, maka poisisi penuh berikutnya adalah di lokasi jmlBilangan - 1, sehingga perulangan for mencetak bilangan dari jmlBilangan - 1 hingga 0.
Mari kita lihat contoh lain yang lebih realistis. Misalkan kita ingin menulis program game, di mana pemain bisa masuk ke dalam game dan keluar dari game setiap saat. Sebagai programmer berorientasi objek yang baik, mungkin kita memiliki kelas bernama Pemain sebagai lambang pemain di dalam game. Daftar pemain yang sedang ada di dalam game, bisa disimpan di dalam array ArrayPemain dengan tipe Pemain[].
Karena jumlah pemain bisa berubah-ubah maka kita bisa menggunakan variabel bantu, misalnya jumlahPemainAktif untuk mencatat banyaknya pemain yang sedang aktif berada di dalam game. Misalnya jumlah maksimum pemain di dalam game adalah 10 orang, maka kita bisa mendeklarasikan variabelnya sebagai :
Pemain[] ArrayPemain = new Pemain[10];  // Hingga 10 pemain.
int jumlahPemainAktif = 0;  // Di awal game, tidak ada pemain yang aktif
Setelah beberapa pemain masuk ke dalam game, variabel jumlahPemainAktif akan lebih dari 0, dan objek pemailn akan disimpan dalam array, misalnya ArrayPemain[0], ArrayPemain[1], ArrayPemain[2], dan seterusnya. Ingat bahwa pemain ArrayPemain[jumlahPemainAktif] tidak ada. Prosedur untuk menambah pemain baru, secara sederhana :
// Tambah pemain di tempat kosong
ArrayPemain[jumlahPemainAktif] = pemainBaru; 
// And increment playerCt to count the new player.
jumlahPemainAktif++;  
Untuk menghapus seorang pemain mungkin sedikit lebih sulit karena kita tidak ingin meninggalkan lubang di tengah-tengah array. Misalnya kita ingin menghapus pemain pada indeks k pada ArrayPemain. Jika kita tidak peduli urutan pemainnya, maka salah satu caranya adalah memindahkan posisi pemain terakhir ke posisi pemain yang meninggalkan game, misalnya :
ArrayPemain[k] = ArrayPemain[jumlahPemainAktif - 1];
jumlahPemainAktif--;
Pemain yang sebelumnya ada di posisi k, tidak lagi ada di dalam array. Pemain yang sebelumnya ada di posisi jumlahPemainAktif -1 sekarang ada di array sebanyak 2 kali. Akan tetapi sekarang ia berada di bagian yang valid, karena nilai jumlahPemainAktif kita kurangi dengan satu. Ingat bahwa setiap elemen di dalam array harus menyimpan satu nilai, akan tetapi satu-satunya nilai dari posisi 0 hingga jumlahPemainAktif - 1 akan tetap diproses seperti biasa.
Misalnya kita ingin menghapus pemain di posisi k, akan tetapi kita ingin agar urutan pemain tetap sama. Untuk melakukannya, semua pemain di posisi k+1 ke atas harus dipindahkan satu posisi ke bawah. Pemain k+ mengganti pemain k yang keluar dari game. Pemain k+2 mengganti pemain yang pindah sebelumnya, dan berikutnya. Kodenya bisa dibuat seperti
for (int i = k+1; i < jumlahPemainAktif; i++) {
    ArrayPemain[i-1] = ArrayPemain[i];
}
jumlahPemainAktif--;
Perlu ditekankan bahwa contoh Pemain di atas memiliki tipe dasar suatu kelas. Elemennya bisa bernilai null atau referensi ke suatu objek yang bertipe Pemain, Objek Pemain sendiri tidak disimpan di dalam array, hanya referensinya saja yang disimpan di sana. Karena aturan pemberian nilai pada Java, objek tersebut bisa saja berupa kelas turunan dari Pemain, sehingga mungkin juga array tersebut menyimpan beberapa jenis Pemain misalnya pemain komputer, pemain manusia, atau pemain lainnya, yang semuanya adalah kelas turunan dari Pemain.
Contoh lainnya, misalnya kelas BentukGeometri menggambarkan suatu bentuk geometri yang bisa digambar pada layar, dan ia memiliki kelas-kelas turunan yang merupakan bentuk-bentuk khusus, seperti garis, kotak, kotak bertepi bulat, oval, atau oval berisi warna, dan sebagainya. (BentukGeometri sendiri bisa berbentuk kelas abstrak, seperti didiskusikan sebelumnya). Kemudian array bertipe BentukGeometri[] bisa menyimpan referensi objek yang bertipe kelas turunan dari BentukGeometri. Misalnya, perhatikan contoh pernyataan berikut
BentukGeometri[] gambar = new BentukGeometri[100]; // Array untuk menyimpan 100 gambar.
gambar[0] = new Kotak();          // Letakkan beberapa objek di dalam array.
gambar[1] = new Garis();          // (Program betulan akan menggunakan beberapa
gambar[2] = new OvalBerwarna();    // parameter di sini
int jmlGambar = 3;  // Lacak jumlah objek di dalam array
bisa diilustrasikan sebagai berikut.
Array tersebut bisa digunakan dalam program gambar. Array bisa digunakan untuk menampung gambar-gambar yang akan ditampilkan. Jika BentukGeometri memiliki metode "void gambarUlang(Graphics g)" untuk menggambar pada grafik g, maka semua grafik dalam array bisa digambar dengan perulangan sederhana
for (int i = 0; i < jmlGambar; i++)
    gambar[i].gambarUlang(g);
Pernyataan "gambar[i].gambarUlang(g);" memanggil metode gambarUlang() yang dimiliki oleh masing-masing gambar pada indeks i di array tersebut. Setiap objek tahu bagaimana menggambar dirinya sendiri, sehingga perintah dalam perulangan tersebut sebetulnya melakukan tugas yang berbeda-beda tergantung pada objeknya. Ini adalah contoh dari polimorfisme dan pengolahan array.

Array Dinamis
Dalam contoh-contoh di atas, ada batas tententu dalam jumlah elemennya, yaitu 100 int, 100 Pemain, dan 100 BentukGeometris. Karena ukuran array tidak bisa berubah, array tersebut hanya bisa menampung maksimum sebanyak elemen yang didefinisikan pada pembuatan array. Dalam banyak kasus, adanya batas maksimum tersebut tidak diinginkan. Kenapa harus bekerja dengan hanya 100 bilangan bulat saja, bukan 101?
Alternatif yang umum adalah membuat array yang sangat besar sehingga bisa digunakan untuk dalam kehidupan sehari-hari. Akan tetapi cara ini tidak baik, karena akan sangat banyak memori komputer yang terbuang karena tidak digunakan. Memori itu mungkin lebih baik digunakan untuk yang lain. Apalagi jika komputer yang akan digunakan tidak memiliki memori yang cukup untuk menjalankan program tersebut.
Tentu saja, cara yang lebih baik adalah apabila kita bisa mengubah ukuran array sesuka kita kapan saja. Ingat bahwa sebenarnya variabel array tidak menyimpan array yang sesungguhnya. Variabel ini hanya menyimpan referensi ke objek tersebut. Kita tidak bisa membuat array tersebut lebih besar, akan tetapi kita bisa membuat array baru yang lebih besar, kemudian mengubah isi variabel array tersebut ke array baru itu.
Tentunya kita harus mengkopi semua isi di array yang lama ke array baru. Array lama akan diambil oleh pemulung memori, karena ia tidak lagi digunakan.
Mari kita lihat kembali contoh game di atas, di mana ArrayPemain adalah array dengan tipe Pemain[] dan jumlahPemainAktif[/code] adalah jumlah pemain yang sudah digunakan array tersebut. Misalnya kita tidak ingin membuat limit banyaknya pemainnya yang bisa ikut main. Jika pemain baru masuk dan array tersebut sudah penuh, kita akan membuat array baru yang lebih besar.
Variabel ArrayPemain akan merujuk pada array baru. Ingat bahwa setelah ini dilakukan, ArrayPemain[0] akan menunjuk pada lokasi memori yang berbeda, akan tetapi nilai ArrayPemain[0] sama dengan sebelumnya. Berikut ini adalah kode untuk melakukan hal di atas:
// Tambah pemain baru, meskipun array sudah penuh
 
if (jumlahPemainAktif == ArrayPemain.length) {
    // Array sudah penuh. Buat array baru yang lebih besar,
    // kemudian kopi isi array lama ke array baru lalu ubah
    // ArrayPemain ke array baru.
    int ukuranBaru = 2 * ArrayPemain.length;  // Ukuran array baru
    Pemain[] temp = new Pemain[ukuranBaru];  // Array baru
    System.arraycopy(ArrayPemain, 0, temp, 0, ArrayPemain.length);
    ArrayPemain = temp;  // Ubah referensi ArrayPemain ke array baru.
}
 
// Di sini kita sudah tahu bahwa pasti ada tempat di array baru.
 
ArrayPemain[jumlahPemainAktif] = pemainBaru; // Tambah pemain baru...
jumlahPemainAktif++;  //    ... dan tambah satu jumlahPemainAktif nya
Jika kita akan melakukan hal ini terus menerus, akan lebih indah jika kita membuat kelas untuk menangani hal ini. Objek mirip array yang bisa berubah ukuran untuk mengakomodasi jumlah data yang bisa ia tampung disebut array dinamis. Array dinamis memiliki jenis operasi yang sama dengan array : mengisi nilai pada posisi tertentu dan mengambil nilai di posisi tertentu. Akan tetapi tidak ada batas maksimum dari jumlah array (hanya tergantung pada jumlah memori komputer yang tersedia). Dalam kelas array dinamis, metode put dan get akan diimplementasikan sebagai metode instansi.
Di sini misalnya, adalah kelas yang mengimplementasikan array dinamis int :
public class ArrayDinamisInt {
    private int[] data;  // Array untuk menyimpan data
    public DynamicArrayOfInt() {
        // Konstruktor.
        data = new int[1];  // Array akan bertambah besar jika diperlukan
    }
 
    public int get(int posisi) {
        // Ambil nilai dari posisi tertentu di dalam array.
        // Karena semua posisi di dalam array adalah nol, maka
        // jika posisi tertentu di luar data array, nilai 0 akan dikembalikan
        if (posisi >= data.length)
            return 0;
        else
            return data[posisi];
    }
 
    public void put(int posisi, int nilai) {
        // Simpan nilai ke posisi yang ditentukan di dalam array
        // Data array tersebut akan bertambah besar jika diperlukan
 
        if (posisi >= data.length) {
            // Posisi yang ditentukan berada di luar array data
            // Besarkan ukuran array 2x lipat. Atau jika ukurannya masih
            // terlalu kecil, buat ukurannya sebesar 2*posisi
 
            int ukuranBaru = 2 * data.length;
            if (posisi >= ukuranBaru)
                ukuranBaru = 2 * posisi;
            int[] dataBaru = new int[ukuranBaru];
            System.arraycopy(data, 0, dataBaru, 0, data.length);
            data = dataBaru;
 
            // Perintah berikut hanya untuk demonstrasi
            System.out.println("Ukuran array dinamis diperbesar menjadi "
                + ukuranBaru);
        }
        data[posisi] = nilai;
    }
 
} // 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. Jika bilangan adalah variable bertipe ArrayDinamisInt, maka perintah bilangan.put(pos,nilai) akan menyimpan bilangan pada posisi pos di array dinamis tersebut. Fungsi bilangan.get(pos) mengambil nilai yang disimpan pada posisi pos.
Pada contoh pertama, kita menggunakan array untuk menyimpan bilangan bulat positif yang dimasukkan oleh user. Kita bisa menulis ulang program tersebut dengan menggunakan ArrayDinamisInt. Referensi ke bilangan[i] diganti dengan bilangan.get[i]. Perintah "bilangan[jmlBilangan] = bil;" kita ganti dengan "bilangan.put(jmlBilangan,bil);". Berikut ini adalah programnya:
public class BalikBilanganInput {
 
    public static void main(String[] args) {
 
        ArrayDinamisInt bilangan;  // Array untuk menyimpan nilai input dari user
        int jmlBilangan;    // Banyaknya bilangan yang sudah disimpan dalam array
        int bil;          // Bilangan yang diambil dari user
 
        bilangan = new ArrayDinamisInt();
        jmlBilangan = 0;                // Belum ada bilangan yang disimpan
 
        System.out.println("Masukkan bilangan bulat positif, masukkan nol untuk mengakhiri.");
 
        while (true) {
            System.out.print("? ");
            bil = KonsolIO.ambilInt();
            if (bil <= 0)
                break;
            bilangan.put(jmlBilangan,bil);
            jmlBilangan++;
        }
 
        System.out.println("\nBilangan yang Anda masukkan dalam urutan terbalik adalah :\n");
 
        for (int i = jmlBilangan - 1; i >= 0; i--) {
            System.out.println( bilangan.get(i) );
        }
 
    } // akhir main();
 
}  // akhir kelas BalikBilanganInput 

Friday

Arraylists dan Vector

ArrayList
Kelas ArrayDinamisInt bisa digunakan jika kita membutuhkan array dengan batas maksimum yang tak terbatas. Akan tetapi jika kita ingin menyimpan BentukGeometri misalnya, kita harus membuat kelas baru. Kelas tersebut mungkin bernama ArrayDinamisBentukGeometri, dan akan tampak sama persis dengan ArrayDinamisInt dengan beberapa perubahan di mana "int" muncul akan diganti dengan "BentukGeometri". Juga demikian jika kita ingin membuat kelas ArrayDinamisDouble, ArrayDinamisPemain, dan sebagainya.
Yang agak sedikit lucu adalah kelas tersebut sangat mirip isinya, hanya kelas-kelasnya saja yang berlainan. Akan sangat lebih baik apabila kita bisa membuat kelas umum yang berlaku untuk semua kelas. Hal ini disebut dengan pemrograman generik. Beberapa bahasa pemrograman seperti C++ memiliki fasilitas untuk melakukan pemrograman generik. Java tidak memiliki fasilitas seperti itu (maksudnya tidak sama persis). Tapi kita bisa membuat sesuatu yang mirip dengan itu pada Java dengan menggunakan struktur data yang memiliki tipe "Object".
Pada Java, setiap kelas adalah kelas turunan dari kelas yang bernama Object. Artinya setiap objek dapat dirujuk oleh variabel bertiipe Object. Semua objek dapat dimasukkan dalam array bertipe Object[]. Jika suatu subrutin memiliki parameter formal bertipe Object, maka objek apapun bisa diberikan kepada subrutin tersebut.
Jika kita buat kelas ArrayDinamisObject, maka kita bisa menyimpan objek apapun. Ini sebenarnya bukan programming generik sebenarnya, dan tidak berlaku untuk tipe primitif seperti int dan double. Sebenarnya, kita tidak perlu membuat kelas ArrayDinamisObject sendiri, karena Java telah memiliki kelas standar yang dinamakan ArrayList yang sifatnya mirip dengan yang kita sebutkan sebelumnya.
ArrayList disimpan dalam paket java.util, jadi jika kita ingin menggunakan kelas ArrayList dalam sebuat program, kita harus memberikan "import java.util.ArrayList;" atau "import java.util.*;" di awal program kita.
Kelas ArrayList berbeda dengan kelas ArrayDinamisInt dalam arti, objek ArrayList selalu memiliki ukuran tertentu, dan kita tidak boleh mengambil posisi di luar ukuran ArrayList. Dalam hal ini, ArrayList mirip seperti array biasa. Akan tetapi, ukuran ArrayList bisa bertambah kapan saja jika diperlukan. Kelas ArrayList memiliki banyak metode instansi. Kita akan jelaskan sebagian yang sangat berguna. Misalnya daftar adalah variabel dengan tipe ArrayList.
  • daftar.size() -- Fungsi ini menghasilkan ukuran ArrayList saat ini. Posisi valid dalam daftar adalah yang bernomor 0 hingga daftar.size() - 1. Ingat bahwa ukurannya bisa nol. Panggilan konstruktor new ArrayList() akan membuat ArrayList dengan ukuran nol.
  • daftar.add(obj) -- Menambah objek di akhir ArrayList, kemudian menambah ukurannya dengan 1. Parameter obj merujuk pada objek dengan tipe apapun, atau bisa bernilai null.
  • daftar.get(N) -- Mengambil nilai yang disimpan pada posisi N pada ArrayList. N harus bertipe bilangan bulat antara 0 hingga daftar.size() - 1. Jika N berada di luar rentang ini, pesan kesalahan akan ditampilkan. Memanggil fungsi ini mirip dengan memanggil array seperti A[N] untuk suatu array A. Akan tetapi kita tidak bisa menggunakan daftar.get(N) pada ekspresi di sebelah kiri daftar.get(N) = 5 tidak boleh dilakukan)
  • daftar.set(N, obj) -- Mengisi suatu objek obj di posisi N dari suatu ArrayList, dan mengganti apapun yang sudah disimpan sebelumnya pada posisi N. Bilangan bulat N harus berada pada rentang 0 hingga daftar.size() - 1. Perintah ini mirip dengan perintah A[N] = obj pada array A.
  • daftar.remove(obj) -- Jika objek tersebut ada di dalam ArrayList, maka objek tersebut akan dibuang. Elemen lain setelah posisi objek tersebut di dalam ArrayList akan digeser satu posisi. Kemudian ukuran ArrayList akan berkurang 1. Jika obj terdapat dalam ArrayList lebih dari satu kali, hanya yang pertama saja yang dibuang.
  • daftar.remove(N) -- Untuk bilangan bulat N, maka perintah ini akan menghapus posisi ke-N pada ArrayList. N harus berada pada rentang 0 hingga daftar.size() - 1. Elemen setelah ini akan digeser satu posisi. Kemudian ukuran ArrayList berkurang 1.
  • daftar.indexOf(obj) -- Fungsi untuk mencari suatu objek obj di dalam ArrayList. Jika objek ditemukan, maka posisinya di dalam ArrayList akan dikembalikan. Jika tidak, maka fungsi ini akan mengembalikan -1.
Misalnya,kita akan membuat pemain dalam game yang digambarkan dengan objek dengan tipe Pemain. Pemain yang berada dalam game disimpan dalam ArrayList bernama paraPemain. Variabel ini dideklarasikan seperti :
ArrayList paraPemain;
dan kita inisialisasikan dengan objek kosong dengan perintah
paraPemain = new ArrayList();
Jika pemainBaru adalah variabel yang bertipe Pemain, maka pemain baru tersebut bisa ditambahkan ke dalam ArrayList dan ke dalam game dengan perintah :
paraPemain.add(pemainBaru);
dan jika pemain nomor i keluar dari game, maka kita hanya perlu memberikan perintah
paraPemain.remove(i);
Atau jika pemain adalah objek bertipe Pemain yang akan kita keluarkan dari game, maka kita bisa menggunakan perintah
paraPemain.remove(pemain);
Semuanya terlihat sangat mudah. Satu-satunya kesulitan yang akan kita temui adalah ketika kita ingin mengambil nilai yang disimpan pada posisi i di dalam ArrayList. Tipe keluaran fungsi ini adalah Object. Dalam hal ini objek yang diambil oleh fungsi ini sebenarnya bertipe Pemain. Supaya kita bisa menggunakan hasil keluarannya, maka kita perlu menggunakan casting tipe untuk mengubahnya menjadi tipe Player, dengan cara :
Pemain pmn = (Pemain)paraPemain.get(i);
Misalnya, jika kelas Pemain memiliki metode instansi yang dinamakan jalan() yang dipanggil ketika seorang pemain menjalankan dadu atau kartu, maka kita bisa menuliskan kode untuk memberi giliran kepada semua pemain untuk jalan, yaitu dengan
for (int i = 0;  i < paraPemain.size();  i++) {
    Pemain pmn = (Pemain)paraPemain.get(i);
    pmn.jalan();
}
Dua baris di dalam perulangan for tersebut dapat digabungkan dengan satu perintah :
((Pemain)paraPemain.get(i)).jalan();
Perintah ini akan mengambil elemen pada ArrayList mengcasting tipenya, kemudian memanggil metode jalan() pada pemain yang baru diambil tersebut. Tanda kurung di sekitar "(Pemain)paraPemain.get(i)" diperlukan karena aturan dalam Java sehingga perintah dalam kurung akan dijalankan terlebih dahulu sebelum metode jalan() dipanggil.

Vector
Kelas ArrayList diperkenalkan pada Java versi 1.2, sebagai salah satu kumpulan kelas yang digunakan untuk bekerja dengan sekumpulan koleksi objek. Jika akan bahas lebih lanjut tentang "kelas koleksi" pada bagian berikutnya. Versi awal Java tidak memiliki ArrayList, akan tetapi memiliki kelas yang sangat mirip yaitu java.util.Vector. Kita masih bisa melihat Vector digunakan pada program lama, dan dalam beberapa kelas standar Java, sehingga kita perlu tahu tentang kelas ini.
Menggunakan Vector mirip dengan menggunakan ArrayList. Perbedaannya adalah nama metode yang berbeda untuk melakukan tugas yang sama, atau nama metode yang berbeda untuk melakukan tugas yang sama.
Seperti ArrayList, suatu Vector mirip dengan array Object yang bisa berkembang jika diperlukan. Konstruktor new Vector() membuat vektor tanpa elemen.
Misalnya vec adalah suatu Vector. Maka :
  • vec.size() adalah fungsi untuk mengembalikan jumlah elemen di dalam vektor.
  • vec.addElement(obj) akan menambahkan Object obj di akhir vektor. Sama dengan metode add() pada ArrayList.
  • vec.removeElement(obj) menghapus obj dari dalam vektor, kalau ada. Hanya objek pertama yang ditemui akan dihapus. Sama dengan remove(obj) pada kelas ArrayList
  • vec.removeElementAt(N) menghapus elemen ke-N. N harus berada pada rentang 0 hingga vec.size() - 1. Sama dengan remove(N) pada ArrayList
  • vec.setSize(N) akan mengubah ukuran vektor menjadi N. Jika di dalam vektor terdapat elemen yang jumlahnya lebih banyak dari N, maka elemen lainnya akan dihapus. Jika lebih sedikit, maka tempat kosong akan diisi dengan null. Kelas ArrayList tidak memiliki metode seperti ini.
Kelas Vector memiiki banyak metode lagi, akan tetapi ini adalah metode yang sering digunakan.