JavaRush /Java blogi /Random-UZ /Iterator naqsh

Iterator naqsh

Guruhda nashr etilgan
Bugun biz Java-da Iterator nima va u nima uchun kerakligi haqida gaplashamiz .
Iterator naqsh - 1
Siz allaqachon bilganingizdek, Java-da Iterator interfeysini amalga oshiradigan ajoyib Collection interfeysi mavjud. Darhol band qilishimga ijozat bering: iterator interfeysini Java-dagi iterator naqshlari bilan aralashtirib yubormaslik kerak! Va aniqlashtirish uchun avvalo interfeysni ko'rib chiqaylik.
"Iterator" so'zini "qo'pol kuch " deb tarjima qilish mumkin . Ya'ni, bu to'plamdagi barcha elementlarni takrorlashi mumkin bo'lgan ma'lum bir ob'ekt. Bundan tashqari, bu sizga to'plamlarning ichki tuzilishi va tartibini o'rganmasdan buni amalga oshirishga imkon beradi.
Keling, bir soniya tasavvur qilaylik, Java-da iterator yo'q. Bunday holda, har bir kishi to'plamlarning chuqurligiga sho'ng'ishi va undan nimasi va nimasi bilan farq qilishini ArrayListchinakam LinkedListtushunishi HashSetkerak TreeSet.

Iterator amalga oshirishi kerak bo'lgan usullar

boolean hasNext()- agar takrorlanadigan ob'ektda (hozirda To'plam) qiymatlar qolgan bo'lsa, trueboshqa qiymatlar bo'lmasa, usul qaytadi false. E next()— to'plamning keyingi elementini (ob'ektini) qaytaradi. Agar boshqa elementlar bo'lmasa (chek yo'q edi hasNext()va biz next()to'plamning oxiriga yetganimizda qo'ng'iroq qildik), usul tashlaydi NoSuchElementException. void remove()- oxirgi marta olingan elementni olib tashlaydi next(). Usul tashlashi mumkin:
  • UnsupportedOperationException, agar bu iterator usulni qo'llab-quvvatlamasa remove()(masalan, faqat o'qish uchun to'plamlarda)
  • IllegalStateException, agar usul next()hali chaqirilmagan bo'lsa yoki remove()oxirgi qo'ng'iroqdan keyin allaqachon chaqirilgan bo'lsa next().
Shunday qilib, List uchun iterator eng keng tarqalgan dastur hisoblanadi. Iterator to'plamning boshidan oxirigacha boradi: u keyingi element mavjudligini tekshiradi va agar mavjud bo'lsa, uni qaytaradi. Ushbu oddiy algoritm asosida tsikl quriladi for-each. Uning kengaytmasi ListIterator. Keling, qo'shimcha java ro'yxatini iterator usullarini ko'rib chiqaylik. Siz ularni katta ehtimol bilan bilasiz:
  • void add(E e)E— ga element kiritadi ;List
  • boolean hasPrevious()— teskari qidirish vaqtida elementlar mavjud truebo'lsa, qaytib keladi ;List
  • int nextIndex()— keyingi elementning indeksini qaytaradi;
  • E previous()— oldingi varaq elementini qaytaradi;
  • int previousIndex()— oldingi element indeksini qaytaradi;
  • void set(E e)- oxirgi qo'ng'iroq next()yoki previous()element bilan qaytarilgan elementni almashtiradi e.
Keling, kichik bir misolni ko'rib chiqaylik. Keling, Listtalabalarga tabrik satrlarini yarataylik:
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("Обучающимся");
list.add("На");
list.add("JavaRush");
Endi biz buning uchun iteratorni olamiz va barcha mavjud satrlarni konsolga chop etamiz:
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}
Endi "darboğaz" paydo bo'ladi: Java to'plamlari, ehtimol siz bilganingizdek (va agar bilmasangiz, buni aniqlang), interfeysni kengaytiring , Iterablelekin bu faqat buni anglatmaydi va iteratorni qo'llab-quvvatlaydi. For ham qo'llab-quvvatlanadi, lekin chaqirilishi kerak : ListSetQueuejava Map iteratorMap.entrySet()
Map<String, Integer> map = new HashMap<>();
Iterator mapIterator = map.entrySet().iterator();
Keyin usul "kalit" - "qiymat" juftligini o'z ichiga olgan next() ob'ektni qaytaradi . EntryKeyin hamma narsa bir xil bo'ladi List:
while (mapIterator.hasNext()) {
    Map.Entry<String, Integer> entry = mapIterator.next();
    System.out.println("Key: " + entry.getKey());
    System.out.println("Value: " + entry.getValue());
}
Siz shunday deb o'ylaysiz: “To'xtang. Biz interfeys haqida gapiramiz va maqolaning sarlavhasida "Naqsh" deyiladi. Ya'ni, iterator naqsh Iterator interfeysi? Yoki interfeys naqshmi? Agar bu so'z birinchi marta paydo bo'lsa, men sizga ma'lumot beraman: naqsh - bu dizayn namunasi, sinf yoki ko'plab o'zaro bog'langan sinflar rioya qilishi kerak bo'lgan muayyan xatti-harakatlar. Java-da iterator ichki tuzilishi iteratsiyani o'z ichiga olgan har qanday ob'ekt uchun amalga oshirilishi mumkin va siz muhokama qilinayotgan usullarning imzosini o'zgartirishingiz mumkin. Naqshni amalga oshirishda asosiy narsa bu sinf rioya qilishi kerak bo'lgan mantiqdir. Iterator interfeysi bir xil nomdagi naqshning shaxsiy amalga oshirilishi bo'lib, u ham tayyor tuzilmalarga ( List, Set, Queue, Map), ham dasturchining ixtiyoriga ko'ra boshqalarga qo'llaniladi. Iterator interfeysini kengaytirish orqali siz naqshni amalga oshirasiz, lekin naqshni amalga oshirish uchun interfeysni kengaytirishingiz shart emas. Oddiy o'xshatish: hamma baliq suzadi, lekin suzuvchi hamma narsa ham baliq emas. Misol tariqasida men... so'zni olishga qaror qildim. Aniqroq aytganda, ot. U qismlardan iborat: prefiks, ildiz, qo'shimcha va tugatish. So'z qismlari uchun biz interfeys WordPartva uni kengaytiruvchi sinflarni yaratamiz: Prefix, Root, Suffix и Ending:
interface WordPart {
    String getWordPart();
}

static class Root implements WordPart {

    private String part;

    public Root(String part) {
        this.part = part;
    }

    @Override
    public String getWordPart() {
        return part;
    }
}

static class Prefix implements WordPart {

    private String part;

    public Prefix(String part) {
        this.part = part;
    }

    @Override
    public String getWordPart() {
        return part;
    }
}

static class Suffix implements WordPart {

    private String part;

    public Suffix(String part) {
        this.part = part;
    }

    @Override
    public String getWordPart() {
        return part;
    }
}

static class Ending implements WordPart {

    private String part;

    public Ending(String part) {
        this.part = part;
    }

    @Override
    public String getWordPart() {
        return part;
    }
}
Keyin sinf Word(so'z) qismlardan iborat bo'ladi va ularga qo'shimcha ravishda biz so'zdagi qismlar sonini aks ettiruvchi butun sonni qo'shamiz:
public class Word {

    private Root root;
    private Prefix prefix;
    private Suffix suffix;
    private Ending ending;
    private int partCount;

    public Word(Root root, Prefix prefix, Suffix suffix, Ending ending) {
        this.root = root;
        this.prefix = prefix;
        this.suffix = suffix;
        this.ending = ending;
        this.partCount = 4;
    }

    public Word(Root root, Prefix prefix, Suffix suffix) {
        this.root = root;
        this.prefix = prefix;
        this.suffix = suffix;
        this.partCount = 3;

    }

    public Word(Root root, Prefix prefix) {
        this.root = root;
        this.prefix = prefix;
        this.partCount = 2;
    }

    public Word(Root root) {
        this.root = root;
        this.partCount = 1;
    }

    public Root getRoot() {
        return root;
    }

    public Prefix getPrefix() {
        return prefix;
    }

    public Suffix getSuffix() {
        return suffix;
    }

    public Ending getEnding() {
        return ending;
    }

    public int getPartCount() {
        return partCount;
    }

    public boolean hasRoot() {
        return this.root != null;
    }

    public boolean hasPrefix() {
        return this.prefix != null;
    }

    public boolean hasSuffix() {
        return this.suffix != null;
    }

    public boolean hasEnding() {
        return this.ending != null;
    }
OK, bizda to'rtta haddan tashqari yuklangan konstruktor bor (oddiylik uchun bizda faqat bitta qo'shimcha bo'lishi mumkin deb faraz qilaylik). Ism bitta prefiksdan iborat bo'lishi mumkin emas, shuning uchun bitta parametrli konstruktor uchun biz ildizni o'rnatamiz. Keling, iterator naqshining amalga oshirilishini yozamiz: WordIterator, 2 usulni bekor qiladi: hasNext()va next():
public class WordIterator implements Iterator<Word.WordPart> {

    private Word word;
    private int wordPartsCount;

    public WordIterator(Word word) {
        this.word = word;
        this.wordPartsCount = word.getPartCount();
    }

    @Override
    public boolean hasNext() {
        if (wordPartsCount == 4) {
            return word.hasPrefix() || word.hasRoot() || word.hasSuffix() || word.hasEnding();
        } else if (wordPartsCount == 3) {
            return word.hasPrefix() || word.hasRoot() || word.hasSuffix();
        } else if (wordPartsCount == 2) {
            return word.hasPrefix() || word.hasRoot();
        } else if (wordPartsCount == 1) {
            return word.hasRoot();
        }
        return false;
    }

    @Override
    public Word.WordPart next() throws NoSuchElementException {
        if (wordPartsCount <= 0) {
            throw new NoSuchElementException("No more elements in this word!");
        }

        try {
            if (wordPartsCount == 4) {
                return word.getEnding();
            }
            if (wordPartsCount == 3) {
                return word.getSuffix();
            }
            if (wordPartsCount == 2) {
                return word.getPrefix();
            }
            return word.getRoot();
        } finally {
            wordPartsCount--;
        }
    }
}
Qolgan narsa iteratorni sinfga tayinlashdir Word:
public class Word implements Iterable<Word.WordPart> {@Override
	public Iterator<WordPart>iterator() {
    		return new WordIterator(this);
	}}
Endi "shoshilinch" so'zining morfemik tahlilini o'tkazamiz:
public class Main {
    public static void main(String[] args) {
        Word.Root root = new Word.Root("беж");
        Word.Prefix prefix = new Word.Prefix("пере");
        Word.Suffix suffix = new Word.Suffix("к");
        Word.Ending ending = new Word.Ending("a");

        Word word = new Word(root, prefix, suffix, ending);

        Iterator wordIterator = word.iterator();
        while (wordIterator.hasNext()) {
            Word.WordPart part = (Word.WordPart) wordIterator.next();
            System.out.println(part.getClass() + ": " + part.getWordPart());
        }
    }
}
E'tibor bering, iterator naqshini amalga oshirishda men quyidagi chiqish tartibini tanladim:
  1. tugash
  2. qo'shimchasi
  3. konsol
  4. ildiz
O'zingizning iteratoringizni loyihalashda siz iteratsiya algoritmini xohlaganingizcha belgilashingiz mumkin. O'qishlaringizga omad!
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION