Rabu, 14 Desember 2011

Iterator (Java)


Interface Collection mendefinisikan beberapa algoritma generik, akan tetapi mungkin kita ingin membuat algoritma generik kita sendiri. Misalnya kita ingin membuat suatu subrutin yang mencetak setiap item di dalam koleksi. Untuk bisa melakukan ini secara generik, kita harus mencari akal bagaimana caranya untuk mengakses setiap item satu per satu.

Kita telah lihat sebelumnya bagaimana caranya untuk data struktur tertentu : Misalnya untuk array, kita bisa menggunakan perulangan for dari item pertama hingga terakhir. Untuk list berantai, kita bisa menggunakan perulangan while dari item pertama hingga kita menemukan null. Untuk pohon biner kita bisa menggunakan subrutin rekursif dengan penelusuran infix.

Koleksi bisa dibuat dalam berbagai bentuk. Dengan keragaman bentuk ini dan bermacam-macam cara untuk menelusurinya, bagaimana kita bisa membuat metode generik yang berlaku untuk semua kenis koleksi? Masalah ini bisa diselesaikan denganiterator.

Iterator adalah objek yang digunakan untuk menelusuri koleksi. Koleksi dengan jenis yang berbeda memiliki jenis iterator yang berbeda pula, akan tetapi semua iterator digunakan dengan cara yang sama. Algoritma yang menggunakan iterator untuk menelusuri koleksi bisa dibuat generik, karena teknik yang sama bisa digunakan untuk beragam jenis koleksi.

Konsep iterator mungkin agak aneh untuk seseorang yang baru menemui konsep pemrgoraman generik, akan tetapi Anda harus mengerti bahwa konsep ini bisa digunakan untuk menyelesaikan masalah sulit dengan cara yang anggun.

Interface Collection memiliki metode yang bisa digunakan untuk mengambil iterator dalam koleksi apapun. Jika kol adalah suatu koleksi, maka kol.iterator() mengembalikan iterator yang bisa digunakan untuk menelusuri koleksi tersebut.

Bayangkan iterator seperti pointer generik yang dimulai dari awal koleksi dan bisa berpindah dari satu item ke item lain. Iterator didefinisikan oleh interface yang bernama Iterator. Interface ini hanya memiliki 3 metode. Jika iter merupakan variabel bertipeIterator, maka :

- iter.next() -- mengembalikan item berikutnya, dan memindahkan iterator ke item berikutnya. Nilai keluarannya bertipeObject. Ingat bahwa kita tidak bisa melihat suatu item tanpa memindahkan iterator ke

- item berikutnya. Jika metode ini dipanggil apabila tidak ada item lagi yang tersisa, ia akan melempar NoSuchElementException.

- iter.hasNext() -- mengembalikan nilai boolean yang memberi tahu apakah ada item berikutnya yang bisa diproses. Kita harus mengetesnya sebelum memanggil iter.next()

- iter.remove() -- jika kita gunakan perintah ini setelah memanggil iter.next(), maka ia akan menghapus item yang baru saja kita lihat. Akan melempar pengecualian UnsupportedOperationException jika koleksi tidak bisa menghapus item.

Dengan menggunakan iterator, kita bisa menulis kode untuk mencetak semua item dalam koleksi apapun. Misalnya kol bertipeCollection. Maka kita bisa menggunakan :
Iterator iter = kol.iterator();
while ( iter.hasNext() ) {
    Object item = iter.next();
    System.out.println(item);
}
Bentuk yang sama bisa digunakan untuk pemrosesan jenis apapun. Misalnya, subrutin berikut ini akan menghapus semua nilainull dari koleksi apapun (selama koleksi itu mengizinkan penghapusan elemen) :
void removeNullValues( Collection coll ) {
    Iterator iter = kol.iterator():
    while ( iter.hasNext() ) {
        Object item = iter.next();
        if (item == null)
            iter.remove();
    }
}
Koleksi bisa menampung objek tipe apa saja, sehingga nilai keluaran iter.next() bertipe Object. Sekarang, tidak ada yang bisa kita lakukan dengan variabel bertipe Object. Dalam situasi praktis, koleksi digunakan untuk menyimpan objek yang bertipe kelas tertentu, kemudian objek dari koleksi itu di-tipe cast ke kelas tersebut sebelum digunakan.

Misalnya, kita menggunakan kelas BentukGeometri. Misalnya kelas ini memiliki metode gambar() untuk menggambar suatu gambar. Maka kita bisa membuat metode generik untuk menggambar semua gambar dalam koleksi BentukGeometri seperti :
void gambarSemuaGambar( Collection koleksiGambar ) {
    // Kondisi Awal: Semua item dalam koleksiGambar tidak berisi null
    //               dan bertipe kelas BentukGeometri
    Iterator iter = koleksiGambar.iterator();
    while ( iter.hasNext() ) {
        BentukGeometri gbr = (BentukGeometri)iter.next();
        gbr.gambar();
    }
}

Kondisi awal dari metode tersebut menyatakan bahwa metode tersebut akan gagal apabila item di dalam koleksi tidak bertipeBentukGeometri. Jika item ini ditemukan, maka tipe-cast "(BentukGeometri)iter.next()" akan melempar pengecualianClassCastException.

Meskipun dalam Java kita tidak bisa memiliki "Koleksi Bentuk Geometri", dan hanya bisa memiliki "Koleksi Object", dalam prakteknya ini bukan masalah besar. Jika hanya perlu ingat objek jenis apa yang kita simpan dalam koleksi kita.

Tidak ada komentar:

Posting Komentar