JavaRush /جاوا بلاگ /Random-SD /اڀرندڙ نموني

اڀرندڙ نموني

گروپ ۾ شايع ٿيل
اڄ اسان ڳالهائينداسين ته ڇا آهي Iterator جاوا ۾ ۽ ان جي ضرورت ڇو آهي.
آئٽرٽر جو نمونو - 1
جئين توهان شايد اڳ ۾ ئي ڄاڻو ٿا، جاوا هڪ شاندار ڪليڪشن انٽرفيس آهي جيڪو آئيٽرٽر انٽرفيس کي لاڳو ڪري ٿو. مون کي فوري طور تي هڪ رزرويشن ڪرڻ ڏيو: آئٽرٽر انٽرفيس کي جاوا ۾ آئٽرٽر نموني سان پريشان نه ٿيڻ گهرجي! ۽ واضح ڪرڻ لاء، اچو ته پهرين انٽرفيس کي ڏسو.
لفظي طور تي، "Iterator" کي ترجمو ڪري سگهجي ٿو "برٽ فورس . " اهو آهي، اهو هڪ خاص ادارو آهي جيڪو مجموعي ۾ سڀني عناصر ذريعي ٻيهر ڪري سگهي ٿو. ان کان علاوه، اهو توهان کي اهو ڪرڻ جي اجازت ڏئي ٿو بغير اندروني ڍانچي ۽ مجموعن جي ترتيب ۾ بغير.
اچو ته هڪ سيڪنڊ لاءِ تصور ڪريون ته جاوا ۾ ڪو به اڀرندڙ نه آهي. انهي صورت ۾، هر هڪ کي گڏ ڪرڻ جي تمام گهڻي کوٽائي ۾ وڃڻو پوندو ۽ صحيح طور تي سمجهڻو پوندو ته ڇا کان ArrayListمختلف آهي . LinkedListHashSetTreeSet

طريقا جيڪي Iterator کي لاڳو ڪرڻ گهرجن

boolean hasNext()- جيڪڏهن اڃا به قدر رهجي ويا آهن ٻيهر قابل اعتراض ۾ (في الحال هڪ مجموعو)، طريقو واپس ايندو true، جيڪڏهن وڌيڪ قدر نه آهن false. E next()- جمع جي ايندڙ عنصر کي واپس ڏئي ٿو (آبجڪٽ). جيڪڏهن ڪو به وڌيڪ عنصر نه آهن (ڪو به چيڪ نه هو hasNext()، ۽ اسان کي سڏيو next()جڏهن اسان گڏ ڪرڻ جي آخر تائين پهچي)، طريقو اڇلائي ڇڏيندو NoSuchElementException. void remove()- ان عنصر کي ختم ڪندو جيڪو آخري ڀيرو حاصل ڪيو ويو next(). طريقو اڇلائي سگھي ٿو:
  • UnsupportedOperationException, جيڪڏهن هي اٽرٽر هن طريقي جي حمايت نٿو ڪري remove()(صرف پڙهڻ واري مجموعن جي صورت ۾، مثال طور)
  • IllegalStateException، جيڪڏهن طريقو next()اڃا تائين نه سڏيو ويو آهي، يا جيڪڏهن اهو remove()اڳ ۾ ئي آخري ڪال کان سڏيو ويو آهي next().
تنهن ڪري، فهرست لاءِ اٽرٽر سڀ کان وڌيڪ عام عمل آهي. آئٽرٽر مجموعي جي شروعات کان ان جي آخر تائين وڃي ٿو: اهو ڏسڻ ۾ اچي ٿو ته ايندڙ عنصر موجود آهي ۽ ان کي واپس ڪري ٿو جيڪڏهن هڪ آهي. هڪ چڪر هن سادي الگورتھم جي بنياد تي ٺهيل آهي for-each. ان جي توسيع ListIterator آهي. اچو ته ڏسو اضافي جاوا لسٽ آئٽرٽر جا طريقا. توهان گهڻو ڪري انهن کي ڄاڻو ٿا:
  • void add(E e)E- ۾ هڪ عنصر داخل ڪري ٿو ؛List
  • boolean hasPrevious()- واپسي ويندي trueجيڪڏهن Listريورس ڳولا دوران عناصر موجود آهن؛
  • int nextIndex()- ايندڙ عنصر جي انڊيڪس واپس ڪندو؛
  • E previous()- پوئين شيٽ عنصر واپس ڪندو؛
  • int previousIndex()- پوئين عنصر جي انڊيڪس واپس ڪندو؛
  • void set(E e)- آخري ڪال ذريعي واپس آيل عنصر کي تبديل ڪندو next()يا previous()عنصر سان e.
اچو ته هڪ ننڍڙو مثال ڏسو. اچو ته Listشاگردن کي سلامن جون لائينون ٺاھيون:
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("Обучающимся");
list.add("На");
list.add("JavaRush");
هاڻي اسان ان لاءِ هڪ آئٽرٽر حاصل ڪنداسين ۽ ڪنسول ۾ موجود سڀئي لائينون پرنٽ ڪنداسين:
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}
ھاڻي ھوندو ھڪڙو ”بٽلينيڪ“: جاوا ڪليڪشن، جيئن توھان ڄاڻو ٿا (۽ جيڪڏھن توھان نه ٿا ڄاڻو، ان جو اندازو لڳايو)، انٽرفيس کي وڌايو، Iterableپر ان جو مطلب اھو نھ آھي ته صرف List، Set۽ Queueھڪ اٽرٽر کي سپورٽ ڪريو. لاء java Map iteratorپڻ سپورٽ ڪئي وئي آهي، پر ان لاء سڏيو وڃي ٿو Map.entrySet():
Map<String, Integer> map = new HashMap<>();
Iterator mapIterator = map.entrySet().iterator();
پوء اهو طريقو next() هڪ اعتراض واپس ڪندو Entryجنهن ۾ "ڪي" - "قدر" جوڙو شامل آهي. پوءِ هر شيءِ ساڳي آهي List:
while (mapIterator.hasNext()) {
    Map.Entry<String, Integer> entry = mapIterator.next();
    System.out.println("Key: " + entry.getKey());
    System.out.println("Value: " + entry.getValue());
}
توهان سوچيو: "روڪ. اسان انٽرفيس جي باري ۾ ڳالهائي رهيا آهيون، ۽ مضمون جو عنوان چوي ٿو "نمون". اهو آهي، iterator نمونو Iterator انٽرفيس آهي؟ يا انٽرفيس هڪ نمونو آهي؟ جيڪڏهن هي لفظ پهريون ڀيرو ظاهر ٿئي ٿو، مان توهان کي هڪ حوالو ڏيان ٿو: هڪ نمونو هڪ ڊزائن جو نمونو آهي، هڪ خاص رويي جو هڪ طبقو يا ڪيترن ئي هڪٻئي سان ڳنڍيل طبقن تي عمل ڪرڻ گهرجي. جاوا ۾ هڪ آئٽرٽر ڪنهن به شئي لاءِ لاڳو ڪري سگهجي ٿو جنهن جي اندروني جوڙجڪ ۾ ٻيهر شامل آهي، ۽ توهان انهن طريقن جي دستخط کي تبديل ڪري سگهو ٿا جن تي بحث ڪيو پيو وڃي. بنيادي شيء جڏهن هڪ نمونو لاڳو ڪرڻ منطق آهي ته طبقي کي عمل ڪرڻ گهرجي. آئيٽرٽر انٽرفيسList, Set, Queue, Map هڪ ئي نالي جي نموني جو هڪ خانگي عمل آهي، جيڪو پروگرامر جي صوابديد تي ٻنهي تيار ڪيل اڏاوتن ( ) ۽ ٻين تي لاڳو ٿئي ٿو . Iterator انٽرفيس کي وڌائڻ سان، توھان ھڪڙو نمونو لاڳو ڪريو ٿا، پر توھان کي انٽرفيس کي وڌائڻ جي ضرورت نھ آھي نموني کي لاڳو ڪرڻ لاءِ. هڪ سادي تشبيهه: سڀ مڇيون ترنديون آهن، پر هر شيءِ جيڪا ترندي آهي اها مڇي ناهي. مثال طور، مون وٺڻ جو فيصلو ڪيو... لفظ. خاص طور تي، هڪ اسم. اهو حصن تي مشتمل آهي: اڳوڻو، روٽ، لاحقه ۽ پڇاڙي. WordPartهڪ لفظ جي حصن لاءِ، اسان هڪ انٽرفيس ۽ ڪلاس ٺاهينداسين جيڪي ان کي وڌائين: 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;
    }
}
پوءِ ڪلاس Word(لفظ) حصن تي مشتمل هوندو، ۽ ان کان علاوه اسان هڪ انٽيجر شامل ڪنداسين جيڪو لفظ ۾ حصن جي تعداد کي ظاهر ڪري ٿو:
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;
    }
ٺيڪ آهي، اسان وٽ چار اوور لوڊ ٿيل تعمير ڪندڙ آهن (سادگي لاءِ، اچو ته فرض ڪريون ته اسان وٽ صرف هڪ لاڳاپو هجي). هڪ اسم هڪ اڳياڙيءَ تي مشتمل نه ٿو ٿي سگهي، تنهنڪري هڪ پيراميٽر سان ٺهڪندڙ لاءِ اسان روٽ مقرر ڪنداسين. ھاڻي اچو ته لکون انٽيليٽر جي نموني تي عمل درآمد: WordIterator، 2 طريقن کي ختم ڪرڻ: hasNext()۽ 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--;
        }
    }
}
باقي اهو آهي ته آئٽرٽر کي ڪلاس ۾ تفويض ڪرڻ Word:
public class Word implements Iterable<Word.WordPart> {@Override
	public Iterator<WordPart>iterator() {
    		return new WordIterator(this);
	}}
هاڻي اچو ته لفظ ”رش“ جو هڪ مورفيمڪ تجزيو ڪريون:
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());
        }
    }
}
مهرباني ڪري نوٽ ڪريو ته منهنجي عمل ۾ آئيٽرٽر نموني جي عمل ۾، مون هيٺين آئوٽ آرڊر کي چونڊيو آهي:
  1. ختم ٿيڻ
  2. لاڳاپو
  3. ڪنسول
  4. جڙ
جڏهن توهان جي پنهنجي آئٽرٽر کي ڊزائين ڪرڻ، توهان بيان ڪري سگهو ٿا iteration algorithm جيئن توهان چاهيو. توهان جي پڙهائي ۾ سٺي قسمت!
تبصرا
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION