1. Iterator paydo bo'lishi tarixi
Siz allaqachon HashSet to'plami bilan tanishgansiz. Va agar siz chindan ham uni o'rganib chiqsangiz, faqat darsni o'qigan bo'lmasangiz, savol tug'ilishi kerak edi:
HashSet'dagi barcha elementlarni ekranga qanday chiqaramiz? Chunki to'plamda get() va set() metodlari yo'q!
Va HashSet bu muammosida yolg'iz emas. HashSetdan tashqari, elementni raqam bo'yicha olish mumkin bo'lmagan ko'plab boshqa kolleksiyalar mavjud, chunki elementlarning aniq tartibi yo'q.
Dasturchilar o'z vaqtida graflar, daraxtlar kabi ko'plab murakkab ma'lumotlar strukturalarini o'ylab topishdi. Yoki, masalan, ro'yxatlar ro'yxati.
Ko'plab konteynerlar yangi elementlar qo'shilganda yoki mavjud elementlar o'chirilganda o'z elementlarining tartibini o'zgartiradi. Masalan, elementlarni o'sib boruvchi tartibda saqlaydigan ro'yxat mavjud va yangi element qo'shilganda, u deyarli har doim ro'yxatning o'rtasiga kiritiladi.
Shunday qilib, bizda elementlarni o'z ichiga olgan konteyner mavjud, lekin aniq tartib mavjud emas.
Agar biz bunday kollektsiyadan barcha elementlarni massiv yoki ro'yxatga nusxalamoqchi bo'lsak, ularning barchasini olishimiz kerak. Biz ularning qaysi tartibda o'tkazilishidan qat'iy nazar, eng muhimi, takrorlanmagan holda o'rganishimiz kerak. Qanday qilib buni qilamiz?
2. Kolektsiyada iterator
Yuqorida keltirilgan muammoni yechish uchun yechim taklif qilindi — iterator.
Iterator — bu kollektsiyaning barcha elementlarini takrorlanmasdan aylanib o'tishga yordam beradigan maxsus obyekt.
Har qanday kollektsiyadan iteratorni olish uchun quyidagi koddan foydalanish mumkin:
Iterator<Type> it = nom.iterator();
Bu erda nom — bu kolleksiya o'zgaruvchining nomi, Type — bu kolleksiyaning elementlari turi. iterator() — bu kolleksiya metodi. it — bu iterator obyekti o'zgaruvchining nomi.
Iterator obyektida 3 ta metod mavjud:
| Method | Tasvir |
|---|---|
|
Koleksiya navbatdagi elementini qaytaradi |
|
Koleksiyada hali bosilmagan elementlar mavjudligini tekshiradi |
|
Koleksiyaning joriy elementini o'chiradi |
Bu metodlar Scanner sinfining metodlariga o'xshash: nextInt() va hasNextInt().
next() metodi iteratorni olgan koleksiya navbatdagi elementini qaytaradi.
hasNext() metodi kollektsiyada hali iterator tomonidan qaytarilmagan elementlar mavjudligini tekshiradi.
HashSet to'plamining barcha elementlarini qanday chiqarish mumkin:
| Kod | Izohlar |
|---|---|
|
HashSet turidagi obyektni yaratamiz, bu esa String turidagi elementlarni saqlaydi.Turli tillarda set ga salomlashuvlarni kiritamiz.set to'plamidan iterator obyektini olamiz.Hali elementlar mavjud bo'lsa Keyingi elementni olamiz Elementni ekranga chiqaramiz |
3. for-each tsikli
Iteratorning asosiy kamchiliklari shundaki, uning yordamida kod for tsiklidan foydalangandan ko'ra yanada murakkabroq bo'ladi.
Keling, taqqoslash uchun ro'yxatni for tsikli va iterator yordamida chiqaramiz:
| Iterator | For tsikll |
|---|---|
|
|
Ha, ArrayList ro'yxatining elementlarini tsiklda aylanishi ancha yaxshi, hamma narsa qisqaroq bo'ladi.
Biroq, Java ishlab chiquvchilari yana bir bor shakarni qo'shishga qaror qilishdi. Va yana bir bor, bu sintaktik shakar edi.
Ular Java-ga yangi turdagi tsikl qo'shishdi va uni for-each deb nomlashdi. Mana, uning umumiy foydalanilishi quyidagi ko'rinishda:
for(Type nom:kolleksiya)
Bu erda kolleksiya — bu kolleksiya o'zgaruvchining nomi, Type — bu kolleksiyaning elementlari turi, va nom — bu o'zgaruvchining nomi, bu esa tsiklning har bir aylanishida kolleksiyadan navbatdagi qiymatni qabul qiladi.
Bu tsikl yashirin iterator orqali barcha elementlarni aylantiradi. Mana, u aslida qanday ishlaydi:
| For-each tsikli | Kompiutor ko'rishi mumkin bo'lgan: Iterator bilan tsikl |
|---|---|
|
|
Kompiulyator sizning kodingizda for-each tsiklini ko'rsa, uni shunchaki o'ngdagi kodga almashtiradi: iterator olish metodini qo'shadi va barcha etishmayotgan metod chaqiruvlarini kiritadi.
Dasturchilar for-each tsiklini juda yaxshi ko'rishadi va kolleksiyaning barcha elementlarini aylantirish kerak bo'lganda deyarli har doim uni ishlatishadi.
Hatto ArrayList ro'yxatini for-each tsikli yordamida aylanishi ham qisqaroq ko'rinadi:
| For-each tsikli | For tsikli |
|---|---|
|
|
4. for-each tsiklida elementni o'chirish
for-each tsiklning bitta kamchiligi bor: u elementlarni to'g'ri o'chirishni bilmaydi. Agar siz bunday kod yozsangiz, xato olasiz.
| Kod | Izoh |
|---|---|
|
Elementni o'chirishda xato yuzaga keladi! |
Bu juda chiroyli va tushunarli kod, lekin ishlamaydi.
Iterator yordamida kollektsiyani aylantirayotganingizda uni o'zgartirish mumkin emas.
Bu cheklovni chetlab o'tishning uchta usuli mavjud.
1 Boshqa tsikldan foydalanish
Agar siz ArrayList kollektsiyasini aylantirayotgan bo'lsangiz, i hisoblagichi bilan oddiy tsikldan foydalanishingiz mumkin.
| Kod |
|---|
|
Lekin bu variant HashSet va HashMap kolleksiyalari uchun mos emas
2 Iteratordan oshkora foydalanish
Iteratorni oshkora ishlatish va uning remove() metodidan foydalanish mumkin.
| Ishlaydigan variant | Ishlamaydigan variant |
|---|---|
|
|
E'tibor bering, remove() metodini iterator obyektida chaqiramiz! Iterator elementning o'chirilishi haqida "biladi" va bu vaziyatni to'g'ri qayta ishlay oladi.
3 Kolleksiyaning nusxasidan foydalanish
Shuningdek, siz koleksiyaning nusxasini yaratishingiz va for-each tsiklda nusxa kolleksiyasidan foydalanishingiz, asl kolleksiyadan elementlarni o'chirishingiz mumkin.
| Kod | Izoh |
|---|---|
|
Kolleksiya nusxasini yaratish juda oson Tsikl nusxa kolleksiyasi iteratoridan foydalanadi. Elementlar list kolleksiyadan o'chiriladi. |
Kolleksiya nusxasi tezda yaratiladi: kolleksiya nusxalanayotganda elementlar ikki marta ko'paytirilmaydi, yangi koleksiyada eski kolleksiyadagi elementlarga havolalar saqlanadi.
GO TO FULL VERSION