Kami sering menggunakan antarmuka berulang yang disediakan oleh JDK untuk mengulangi koleksi Java.
Iterator iterator = list.iterator (); while (iterator.hasnext ()) {string string = iterator.next (); // lakukan sesuatu} Iterasi sebenarnya dapat dipahami sebagai traversal. Ini adalah kelas metode yang menstandarkan traversal dari semua objek di berbagai wadah. Ini adalah pola desain yang sangat khas. Pola Iterator adalah metode akses standar yang digunakan untuk melintasi kelas koleksi. Itu abstrak mengakses logika dari berbagai jenis kelas koleksi, sehingga menghindari mengekspos struktur internal koleksi ke klien. Beginilah cara kita menghadapinya ketika tidak ada iterator. sebagai berikut:
Untuk array kami menggunakan subskrip untuk memproses:
int [] array = int int [10]; untuk (int i = 0; i <arrays.length; i ++) {int a = array [i]; // lakukan sesuatu} Beginilah penanganan arraylist:
Daftar <String> Daftar = ArrayList baru <string> (); untuk (int i = 0; i <list.size (); i ++) {string string = list.get (i); // lakukan sesuatu} Untuk kedua metode, kami selalu tahu sebelumnya struktur internal koleksi. Kode akses dan koleksi itu sendiri digabungkan dengan ketat dan tidak dapat memisahkan logika akses dari kelas pengumpulan dan kode klien. Pada saat yang sama, setiap koleksi sesuai dengan metode traversal, dan kode klien tidak dapat digunakan kembali. Dalam aplikasi praktis, cukup merepotkan untuk mengintegrasikan dua set di atas. Jadi untuk menyelesaikan masalah di atas, mode iterator kosong, dan selalu menggunakan logika yang sama untuk melintasi koleksi. Ini membuat klien itu sendiri tidak perlu untuk mempertahankan struktur internal koleksi, dan semua negara bagian internal dipertahankan oleh iterator. Klien tidak pernah berurusan dengan kelas pengumpulan secara langsung. Itu selalu mengontrol iterator dan mengirimkannya "maju", "mundur", dan "mengambil elemen saat ini" ke sana, dan secara tidak langsung dapat melintasi seluruh koleksi.
Di atas hanyalah penjelasan singkat tentang pola iterator. Mari kita lihat antarmuka Iterator di Java untuk melihat bagaimana mengimplementasikannya.
1. Java.util.iterator
Di Java, Iterator adalah antarmuka, yang hanya memberikan aturan dasar berulang. Di JDK, ini didefinisikan sebagai ini: Iterator yang berulang pada koleksi. Iterator menggantikan enumerasi dalam kerangka Koleksi Java. Ada dua perbedaan antara iterator dan enumerasi:
1. Iterator memungkinkan penelepon untuk menghapus elemen dari koleksi yang ditunjuk oleh iterator selama iterasi menggunakan semantik yang terdefinisi dengan baik.
2. Nama metode telah ditingkatkan.
Definisi antarmuka adalah sebagai berikut:
Iterator Antarmuka Publik {Boolean HasNext (); Objek selanjutnya (); void remeFe ();} di dalam:
Object Next (): Mengembalikan referensi ke elemen yang baru saja dilintasi Iterator. Nilai pengembalian adalah objek, yang perlu dilemparkan ke jenis yang Anda butuhkan.
boolean hasnext (): Menentukan apakah ada elemen yang tersedia dalam wadah untuk diakses
batal lepas (): Lepaskan elemen yang baru saja dilintasi iterator
Bagi kami, kami hanya perlu menggunakan selanjutnya () dan hasnext () untuk menyelesaikan iterasi. sebagai berikut:
untuk (iterator it = c.iterator (); it.hasnext ();) {objek o = it.next (); // lakukan sesuatu} Penjelasan sebelumnya adalah bahwa Iterator memiliki keuntungan besar, yaitu, kita tidak perlu mengetahui hasil internal set. Struktur internal dan keadaan set dipertahankan oleh iterator. Kami menilai dan mendapatkan elemen berikutnya melalui metode terpadu HasNext () dan Next (). Adapun implementasi internal spesifik, kita tidak perlu khawatir tentang hal itu. Tetapi sebagai programmer yang memenuhi syarat, sangat penting untuk mengetahui implementasi iterator. Kode sumber ArrayList dianalisis di bawah ini.
2. Implementasi iterator untuk setiap koleksi
Mari kita analisis implementasi iterator dari ArrayList. Faktanya, jika kita memahami struktur data arraylist, hashset, dan treeset dan mengimplementasikannya secara internal, kita akan yakin tentang bagaimana mereka mengimplementasikan iterator. Karena implementasi internal ArrayList menggunakan array, kita hanya perlu mencatat indeks posisi yang sesuai, dan implementasi metodenya relatif sederhana.
2.1. Implementasi arraylist iterator
Inside ArrayList, pertama -tama mendefinisikan ITR kelas dalam, yang mengimplementasikan antarmuka iterator, sebagai berikut:
kelas pribadi ITR mengimplementasikan iterator <E> {// lakukan sesuatu} Dan metode iterator () dari arraylist diimplementasikan:
Iterator publik <E> iterator () {return new iTr ();} Jadi metode arraylist.iterator () mengembalikan kelas dalam ITR (), jadi yang perlu kita pedulikan sekarang adalah implementasi kelas dalam ITR ():
Tiga variabel tipe-int didefinisikan di dalam ITR: Kursor, Lastret, dan PrecepertModCount. di mana kursor mewakili posisi indeks dari elemen berikutnya, dan lastret mewakili posisi indeks dari elemen sebelumnya
kursor int; int lastret = -1; int diharapkanmodcount = modcount;
Dari definisi kursor dan lastret, dapat dilihat bahwa Lastret selalu menjadi satu kurang dari kursor, sehingga metode implementasi hasnext () sangat sederhana. Anda hanya perlu menilai apakah kursor dan lastret sama.
public boolean hasnext () {return kursor! = size;} Implementasi Next () sebenarnya relatif sederhana. Cukup kembalikan elemen pada posisi indeks kursor, lalu ubah kursor dan lastret
publik e next () {checkForComodification (); int i = kursor; // Catat posisi indeks jika (i> = size) // Jika elemen yang diperoleh lebih besar dari jumlah elemen pengumpulan, pengecualian dilemparkan melempar nosuchelementException baru (); objek [] elementData = arraylist.this.elementData; if (i> = elementData.length) melempar concurrentmodificationException baru (); kursor = i + 1; // kursor + 1Return (e) elementData [lastret = i]; // lastret + 1 dan kembalikan elemen di kursor} CheckForComodification () terutama digunakan untuk menentukan apakah jumlah modifikasi dari suatu set adalah legal, yaitu, untuk menentukan apakah set telah dimodifikasi selama proses traversal. ModCount digunakan untuk merekam jumlah modifikasi koleksi ArrayList, diinisialisasi ke 0, dan setiap kali koleksi dimodifikasi sekali (pembaruan internal tidak diperhitungkan untuk struktur), seperti Tambah, Hapus dan metode lain, MODCount + 1, jadi jika ModCount tetap tidak berubah, itu berarti bahwa konten koleksi belum dimodifikasi. Mekanisme ini terutama digunakan untuk mengimplementasikan mekanisme kegagalan pengumpulan arraylist yang cepat. Dalam koleksi Java, sebagian besar koleksi memiliki mekanisme kegagalan cepat. Saya tidak akan membicarakannya di sini, dan saya akan membicarakannya nanti. Oleh karena itu, untuk memastikan bahwa tidak ada kesalahan selama proses traversal, kami harus memastikan bahwa tidak akan ada modifikasi struktural untuk pengumpulan selama proses traversal (kecuali untuk metode Hapus). Jika kesalahan pengecualian terjadi, kita harus hati -hati memeriksa apakah program memiliki kesalahan alih -alih tidak memprosesnya setelah tangkapan.
final void checkForComodification () {if (modcount! = diharapkanmodcount) lempar concurrentModificationException baru ();} Metode Remove () adalah implementasi, yang memanggil metode hapus () dari arraylist itu sendiri untuk menghapus elemen posisi lastret, dan kemudian memodifikasi MODCount.
public void remove() {if (lastRet < 0)throw new IllegalStateException();checkForComodification();try {ArrayList.this.remove(lastRet);cursor = lastRet;lastRet = -1;expectedModCount = modCount;} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException ();}}Di atas adalah metode implementasi Iterasi Iterator Koleksi Java yang diperkenalkan kepada Anda oleh editor. Saya harap ini akan membantu Anda. Jika Anda memiliki pertanyaan, silakan tinggalkan saya pesan dan editor akan membalas Anda tepat waktu. Terima kasih banyak atas dukungan Anda ke situs web Wulin.com!