1. Latar belakang tentang bagaimana iterator muncul
Anda sudah biasa dengan HashSet
. Jika anda benar-benar menyiasatnya, selain daripada membaca pelajaran, maka anda sepatutnya bertanya soalan ini:
Bagaimanakah saya boleh memaparkan senarai semua elemen HashSet pada skrin? Lagipun, antara muka tidak mempunyai get()
dan set()
kaedah!
Dan HashSet
tidak bersendirian dalam had ini. Di samping itu HashSet
, terdapat banyak koleksi lain yang tidak membenarkan unsur-unsur diambil oleh indeks, kerana unsur-unsur tidak mempunyai susunan yang ditentukan.
Selama bertahun-tahun, pengaturcara telah mencipta banyak struktur data yang kompleks, seperti graf dan pepohon. Atau senarai senarai.
Banyak bekas mengubah susunan elemennya apabila elemen baharu ditambah atau elemen sedia ada dialih keluar. Sebagai contoh, senarai menyimpan elemen dalam susunan tertentu dan apabila elemen baharu ditambah, ia hampir selalu disisipkan di tengah-tengah senarai.
Dan kami juga mendapat situasi di mana terdapat bekas yang menyimpan elemen tetapi tidak dalam sebarang susunan tetap.
Sekarang katakan kita mahu menyalin semua elemen daripada koleksi sedemikian ke dalam tatasusunan atau senarai. Kita perlu mendapatkan semua elemen. Kami tidak mempedulikan susunan kami mengulangi elemen — perkara penting ialah tidak mengulangi elemen yang sama lebih daripada sekali. Bagaimana kita melakukannya?
2. Iterator untuk koleksi
Iterator telah dicadangkan sebagai penyelesaian kepada masalah di atas.
Iterator ialah objek khas yang dikaitkan dengan koleksi, yang membantu melintasi semua elemen koleksi tanpa mengulangi apa-apa.
Anda boleh menggunakan kod berikut untuk mendapatkan iterator untuk sebarang koleksi:
Iterator<Type> it = name.iterator();
Di manakah name
nama pembolehubah koleksi, Type
ialah jenis elemen koleksi, iterator()
merupakan salah satu kaedah koleksi, dan it
nama pembolehubah lelaran.
Objek iterator mempunyai 3 kaedah:
Kaedah | Penerangan |
---|---|
|
Mengembalikan elemen seterusnya dalam koleksi |
|
Menyemak sama ada terdapat sebarang elemen yang belum dilalui |
|
Mengalih keluar elemen semasa koleksi |
Kaedah ini agak serupa dengan kelas nextInt)
dan hasNextInt()
kaedah Pengimbas.
Kaedah ini next()
mengembalikan elemen koleksi seterusnya dari mana kami mendapat iterator.
Kaedah hasNext()
menyemak sama ada koleksi mempunyai elemen tambahan yang belum dikembalikan oleh iterator.
Berikut ialah cara untuk memaparkan semua elemen a HashSet
:
Kod | Nota |
---|---|
|
Buat HashSet objek yang menyimpan String elemen. Kami menambah ucapan dalam pelbagai bahasa kepada set pembolehubah. Dapatkan objek iterator untuk set set. Selagi masih ada elemen Dapatkan elemen seterusnya Paparkan elemen pada skrin |
3. For-each
gelung
Kelemahan utama iterator ialah kod anda menjadi lebih rumit daripada menggunakan for
gelung.
Untuk membandingkan, mari paparkan senarai menggunakan for
gelung dan juga menggunakan iterator:
Iterator | untuk gelung |
---|---|
|
|
Ya, adalah lebih baik untuk melintasi elemen menggunakan ArrayList
gelung — semuanya ternyata lebih pendek.
Tetapi pencipta Java sekali lagi memutuskan untuk mencurahkan sedikit gula kepada kami. Nasib baik bagi kami, ia adalah gula sintaksis .
Mereka memberikan Java jenis gelung baharu dan memanggilnya gelung for-each
. Begini rupanya secara umum:
for(Type name:collection)
Di manakah collection
nama pembolehubah koleksi, Type
ialah jenis elemen dalam koleksi, dan name
ialah nama pembolehubah yang mengambil nilai seterusnya daripada koleksi pada setiap lelaran gelung.
Gelung jenis ini berulang melalui semua elemen koleksi menggunakan lelaran tersirat. Inilah cara ia sebenarnya berfungsi:
Untuk-setiap gelung | Perkara yang dilihat oleh pengkompil: Gelung dengan lelaran |
---|---|
|
|
Apabila pengkompil menemui for-each
gelung dalam kod anda, ia hanya menggantikannya dengan kod di sebelah kanan: ia menambah panggilan untuk mendapatkan lelaran bersama-sama dengan mana-mana panggilan kaedah lain yang hilang.
Pengaturcara menyukai for-each
gelung dan hampir selalu menggunakannya apabila mereka perlu mengulangi semua elemen koleksi.
Malah mengulang ArrayList
senarai menggunakan for-each
gelung kelihatan lebih pendek:
Untuk-setiap gelung | untuk gelung |
---|---|
|
|
4. Mengalih keluar elemen dalam for-each
gelung
Gelung for-each
mempunyai satu kelemahan: ia tidak boleh mengalih keluar elemen dengan betul. Jika anda menulis kod seperti ini, anda akan mendapat ralat.
Kod | Catatan |
---|---|
|
Operasi alih keluar akan menghasilkan ralat! |
Ini adalah kod yang sangat bagus dan mudah difahami, tetapi ia tidak akan berfungsi.
Anda tidak boleh menukar koleksi semasa anda melintasinya dengan iterator.
Terdapat tiga cara untuk mengatasi had ini.
1. Gunakan jenis gelung yang berbeza
When traversing an ArrayList collection
, anda boleh menggunakan gelung biasa dengan i
pembolehubah pembilang.
Kod |
---|
|
Walau bagaimanapun, pilihan ini tidak sesuai untuk HashSet
dan HashMap
koleksi
2. Gunakan iterator eksplisit
Anda boleh menggunakan iterator secara eksplisit dan memanggil kaedahnya remove()
.
Versi yang berfungsi | Versi yang tidak berfungsi |
---|---|
|
|
Perhatikan bahawa kami memanggil remove()
kaedah pada objek iterator! Peulang sedar bahawa item telah dialih keluar dan boleh mengendalikan situasi dengan betul.
3. Gunakan salinan koleksi
Anda juga boleh membuat salinan koleksi dan kemudian menggunakan salinan dalam gelung for-each
dan memadamkan elemen daripada koleksi asal.
Kod | Catatan |
---|---|
|
Mencipta salinan koleksi adalah sangat mudah Gelung menggunakan lelaran untuk salinan koleksi. Elemen dialih keluar daripada list koleksi. |
Koleksi disalin agak cepat, kerana elemen itu sendiri tidak diduplikasi. Sebaliknya, koleksi baharu menyimpan rujukan kepada elemen yang telah wujud dalam koleksi lama.
GO TO FULL VERSION