1. Latar belakang bagaimana iterator muncul
Anda sudah familiar dengan HashSet
. Jika Anda benar-benar menyelidikinya, lebih dari sekedar membaca pelajaran, maka Anda seharusnya mengajukan pertanyaan ini:
Bagaimana cara menampilkan daftar semua elemen HashSet di layar? Lagi pula, antarmuka tidak memiliki get()
dan set()
metode!
Dan HashSet
tidak sendirian dalam keterbatasan ini. Selain HashSet
, ada banyak koleksi lain yang tidak mengizinkan elemen diambil dengan indeks, karena elemen tidak memiliki urutan yang ditentukan.
Selama bertahun-tahun, pemrogram telah menemukan banyak struktur data yang kompleks, seperti grafik dan pohon. Atau daftar daftar.
Banyak wadah mengubah urutan elemennya saat elemen baru ditambahkan atau elemen yang sudah ada dihapus. Misalnya, daftar menyimpan elemen dalam urutan tertentu, dan saat elemen baru ditambahkan, elemen tersebut hampir selalu disisipkan di tengah daftar.
Dan kami juga mendapatkan situasi di mana ada wadah yang menyimpan elemen tetapi tidak dalam urutan tetap.
Sekarang katakanlah kita ingin menyalin semua elemen dari koleksi tersebut ke dalam array atau daftar. Kita perlu mendapatkan semua elemen. Kita tidak peduli dengan urutan iterasi pada elemen — hal yang penting adalah tidak melakukan iterasi pada elemen yang sama lebih dari sekali. Bagaimana kita melakukannya?
2. Iterator untuk koleksi
Iterator diusulkan sebagai solusi untuk masalah di atas.
Iterator adalah objek khusus yang terkait dengan koleksi, yang membantu melintasi semua elemen koleksi tanpa mengulanginya.
Anda dapat menggunakan kode berikut untuk mendapatkan iterator untuk koleksi apa pun:
Iterator<Type> it = name.iterator();
Di mana name
nama variabel koleksi, Type
jenis elemen koleksi, iterator()
salah satu metode koleksi, dan it
nama variabel iterator.
Objek iterator memiliki 3 metode:
metode | Keterangan |
---|---|
|
Mengembalikan elemen berikutnya dalam koleksi |
|
Memeriksa apakah ada elemen yang belum dilalui |
|
Menghapus elemen koleksi saat ini |
Metode ini agak mirip dengan kelas nextInt)
dan hasNextInt()
metode Scanner.
Metode ini next()
mengembalikan elemen koleksi berikutnya dari mana kita mendapatkan iteratornya.
Metode hasNext()
memeriksa apakah koleksi memiliki elemen tambahan yang belum dikembalikan oleh iterator.
Berikut cara menampilkan semua elemen a HashSet
:
Kode | Catatan |
---|---|
|
Buat HashSet objek yang menyimpan String elemen. Kami menambahkan salam dalam berbagai bahasa ke set variabel. Dapatkan objek iterator untuk set set. Selama masih ada elemen Dapatkan elemen selanjutnya Tampilkan elemen di layar |
3. For-each
putaran
Kerugian utama dari iterator adalah kode Anda menjadi lebih rumit daripada menggunakan for
loop.
Untuk membandingkan, mari tampilkan daftar menggunakan for
loop dan juga menggunakan iterator:
Iterator | untuk putaran |
---|---|
|
|
Ya, jauh lebih baik untuk melintasi elemen menggunakan ArrayList
loop — semuanya ternyata lebih pendek.
Tapi pencipta Java kembali memutuskan untuk menuangkan gula pada kami. Beruntung bagi kami, itu adalah gula sintaksis .
Mereka memberi Java jenis loop baru dan menyebutnya loop for-each
. Begini tampilannya secara umum:
for(Type name:collection)
Di mana collection
nama variabel koleksi, Type
jenis elemen dalam koleksi, dan name
nama variabel yang mengambil nilai berikutnya dari koleksi pada setiap iterasi loop.
Jenis loop ini mengiterasi semua elemen koleksi menggunakan iterator implisit. Inilah cara kerjanya:
Untuk-setiap loop | Apa yang dilihat oleh kompiler: Ulangi dengan iterator |
---|---|
|
|
Ketika kompiler menemukan for-each
loop dalam kode Anda, itu hanya menggantinya dengan kode di sebelah kanan: itu menambahkan panggilan untuk mendapatkan iterator bersama dengan panggilan metode lain yang hilang.
Pemrogram menyukai for-each
loop dan hampir selalu menggunakannya saat mereka perlu mengulangi semua elemen koleksi.
Bahkan mengulangi ArrayList
daftar menggunakan for-each
loop terlihat lebih pendek:
Untuk-setiap loop | untuk putaran |
---|---|
|
|
4. Menghapus elemen dalam satu for-each
lingkaran
Loop for-each
memiliki satu kelemahan: tidak dapat menghapus elemen dengan benar. Jika Anda menulis kode seperti ini, Anda akan mendapatkan kesalahan.
Kode | Catatan |
---|---|
|
Operasi hapus akan menghasilkan kesalahan! |
Ini adalah kode yang sangat bagus dan mudah dipahami, tetapi tidak akan berhasil.
Anda tidak dapat mengubah koleksi saat Anda melintasinya dengan iterator.
Ada tiga cara untuk mengatasi batasan ini.
1. Gunakan jenis loop yang berbeda
When traversing an ArrayList collection
, Anda dapat menggunakan loop biasa dengan i
variabel penghitung.
Kode |
---|
|
Namun, opsi ini tidak cocok untuk HashSet
dan HashMap
koleksi
2. Gunakan iterator eksplisit
Anda dapat menggunakan iterator secara eksplisit dan memanggil metodenya remove()
.
Versi yang berfungsi | Versi yang tidak berfungsi |
---|---|
|
|
Perhatikan bahwa kami memanggil remove()
metode pada objek iterator! Iterator menyadari bahwa item tersebut telah dihapus dan dapat menangani situasi dengan benar.
3. Gunakan salinan koleksi
Anda juga dapat membuat salinan koleksi lalu menggunakan salinan tersebut dalam satu for-each
lingkaran dan menghapus elemen dari koleksi asli.
Kode | Catatan |
---|---|
|
Membuat salinan koleksi sangat mudah Loop menggunakan iterator untuk salinan koleksi. Elemen dihapus dari list koleksi. |
Koleksinya disalin agak cepat, karena elemennya sendiri tidak diduplikasi. Sebagai gantinya, koleksi baru menyimpan referensi ke elemen yang sudah ada di koleksi lama.
GO TO FULL VERSION