"Hai, Amigo!"

"Hai, Ellie!"

"Hari ini saya ingin memberitahu anda tentang iterator."

"Iterators dicipta secara praktikal pada masa yang sama dengan koleksi. Tujuan utama koleksi adalah untuk menyimpan elemen, dan tujuan utama iterator adalah untuk mendapatkan semula elemen ini satu demi satu."

"Apakah yang sukar untuk mendapatkan satu set elemen?"

"Pertama, elemen dalam beberapa koleksi, seperti Set, tidak mempunyai susunan yang ditetapkan dan/atau pesanan berubah secara berterusan."

"Kedua, sesetengah struktur data mungkin menyimpan objek dengan cara yang sangat kompleks: dalam kumpulan yang berbeza, senarai, dsb. Dalam erti kata lain, mengedarkan semua elemen mengikut urutan akan menjadi tugas yang tidak remeh."

"Ketiga, koleksi cenderung untuk berubah. Katakan anda memutuskan untuk memaparkan keseluruhan kandungan koleksi, tetapi betul-betul di tengah-tengah output JVM bertukar ke urutan lain yang menggantikan separuh daripada elemen koleksi. Jadi bukannya output, anda mendapat siapa tahu."

"Hmm..."

"Tetapi! Ini betul-betul jenis masalah yang boleh diselesaikan oleh iterator. Iterator ialah objek khas dalam koleksi yang, dalam satu pihak, mempunyai akses kepada semua data peribadinya dan mengetahui struktur dalamannya, dan sebaliknya. , melaksanakan antara muka Iterator awam, yang membolehkan semua orang mengetahui cara untuk bekerja dengannya. "

"Sesetengah iterator mempunyai tatasusunan dalaman di mana semua elemen koleksi disalin apabila iterator dibuat. Ini memastikan bahawa sebarang perubahan berikutnya pada koleksi tidak akan menjejaskan bilangan atau susunan elemen."

"Saya rasa anda telah menemui perkara ini semasa bekerja dengan setiap . Anda tidak boleh menggelungkan koleksi dan mengalih keluar elemen daripadanya secara serentak. Ini semua adalah tepat kerana cara iterator berfungsi."

"Dalam koleksi baharu yang ditambahkan pada pustaka concurrency, iterator diolah semula untuk menghapuskan masalah ini."

"Biar saya ingatkan anda cara iterator berfungsi."

"Java mempunyai antara muka Iterator khas. Berikut ialah kaedahnya:"

Kaedah antara muka Iterator<E> Penerangan
boolean hasNext() Semak sama ada terdapat sebarang elemen lagi
E next() Mengembalikan elemen semasa dan bergerak ke seterusnya.
void remove() Mengeluarkan elemen semasa

"Sebuah iterator membolehkan anda mendapatkan semua elemen koleksi secara berturut-turut. Lebih logik untuk menganggap iterator sebagai sesuatu seperti InputStream — ia mempunyai semua data, tetapi tugasnya adalah untuk mengeluarkannya secara berurutan."

"   Kaedah () seterusnya mengembalikan elemen seterusnya dalam koleksi."

" Kaedah hasNext () digunakan untuk menyemak sama ada terdapat sebarang elemen lagi."

"Dan keluarkan () mengalih keluar elemen semasa."

"Ada soalan?"

"Mengapa kaedah mempunyai nama yang aneh? Mengapa tidak isEmpty() dan getNextElement()?"

"Bukankah itu lebih masuk akal?"

"Ia akan lebih masuk akal, tetapi nama-nama itu berasal dari bahasa C++, di mana iterator muncul lebih awal."

"I see. Jom sambung."

"Selain iterator, terdapat juga antara muka Iterable, yang mesti dilaksanakan oleh semua koleksi yang menyokong iterator. Ia mempunyai satu kaedah:"

Kaedah antara muka Iterable<T> Penerangan
Iterator<T>iterator() Mengembalikan objek lelaran

"Anda boleh menggunakan kaedah ini pada mana-mana koleksi untuk mendapatkan objek iterator untuk berjalan melalui elemennya. Mari kita lihat semua elemen dalam TreeSet : "

Contoh
TreeSet<String> set = new TreeSet<String>();
Iterator<String> iterator = set.iterator();

while (iterator.hasNext())
{
 String item = iterator.next();
 System.out.println(item);
}

"Menggunakan lelaran seperti ini tidak begitu mudah — terdapat terlalu banyak kod yang tidak diperlukan dan jelas. Keadaan menjadi lebih mudah apabila gelung untuk setiap setiap muncul di Jawa."

"Kini kod ini lebih padat dan boleh dibaca:"

Sebelum ini Selepas
TreeSet<String> set = new TreeSet<String>();
Iterator<String> iterator = set.iterator();

while (iterator.hasNext())
{
 String item = iterator.next();
 System.out.println(item);
}
TreeSet<String> set = new TreeSet<String>();

for(String item : set)
{
 System.out.println(item);
}

"Ini adalah kod yang sama! Iterator digunakan dalam kedua-dua kes."

"Cuma penggunaannya disembunyikan dalam gelung untuk setiap . Ambil perhatian bahawa kod di sebelah kanan tidak mempunyai teks merah sama sekali. Penggunaan iterator disembunyikan sepenuhnya."

"Satu gelung untuk-setiap digunakan untuk mana-mana objek yang menyokong iterator. Dalam erti kata lain, anda boleh menulis kelas anda sendiri, menambah kaedah iterator () padanya dan menggunakan objeknya dalam untuk setiap binaan."

"Wah! Sudah tentu, saya tidak berminat untuk menulis koleksi dan iterator saya sendiri, tetapi prospeknya masih menarik. Saya akan mencatatnya."

Selain itu, terdapat satu lagi jenis lelaran popular yang mempunyai antara muka sendiri. Saya bercakap tentang iterator untuk senarai, iaitu ListIterator .

"Tidak kira pelaksanaannya, senarai mengekalkan susunan elemen, yang menjadikan kerja dengan mereka melalui iterator sedikit lebih mudah."

"Berikut ialah kaedah antara muka ListIterator <E>:"

Kaedah Penerangan
boolean hasNext() Semak sama ada terdapat lagi elemen di hadapan.
E next() Mengembalikan elemen seterusnya.
int nextIndex() Mengembalikan indeks elemen seterusnya
void set(E e) Menukar nilai elemen semasa
boolean hasPrevious() Semak sama ada terdapat sebarang unsur di belakang.
E previous() Mengembalikan elemen sebelumnya
int previousIndex() Mengembalikan indeks elemen sebelumnya
void remove() Mengeluarkan elemen semasa
void add(E e) Menambah elemen pada penghujung senarai.

"Dengan kata lain, di sini kita boleh bergerak ke hadapan dan ke belakang. Dan terdapat beberapa ciri kecil lain."

"Nah, benda yang menarik tu. Di mana ia digunakan?"

"Katakanlah anda ingin bergerak ke sana ke mari pada senarai terpaut. Operasi get akan menjadi agak perlahan, tetapi operasi seterusnya() akan menjadi sangat pantas."

"Hmm. Awak yakinkan saya. Saya akan simpan dalam fikiran."

"Terima kasih, Ellie!"