Menu
Coddy logo textTech

Yineleyici Kalıbı

Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 76 / 87.

Iterator Kalıbı, temel yapısını açığa çıkarmadan bir koleksiyonun öğelerine sıralı olarak erişmenin bir yolunu sağlayan davranışsal bir tasarım kalıbıdır. Bir dizi, bağlı liste veya ağaçla çalışıyor olmanız fark etmeksizin, yineleyici öğeler arasında gezinmek için size standart bir yol sunar.

Bu desen, dolaşma mantığını koleksiyonun kendisinden ayırır. İki ana bileşen içerir: öğeler arasında dolaşmak için yöntemleri tanımlayan bir Iterator arayüzü ve koleksiyonu için yineleyiciler oluşturan bir Iterable (veya Aggregate):

interface Iterator<T> {
    boolean hasNext();
    T next();
}

interface Container<T> {
    Iterator<T> createIterator();
}

class BookShelf implements Container<String> {
    private String[] books;
    private int count = 0;
    
    public BookShelf(int size) {
        books = new String[size];
    }
    
    public void addBook(String book) {
        books[count++] = book;
    }
    
    public Iterator<String> createIterator() {
        return new BookIterator();
    }
    
    private class BookIterator implements Iterator<String> {
        private int index = 0;
        
        public boolean hasNext() {
            return index < count;
        }
        
        public String next() {
            return books[index++];
        }
    }
}

Yineleyici, kendi gezinme durumunu koruyarak birden fazla yineleyicinin aynı koleksiyonda birbirinden bağımsız şekilde gezinmesine olanak tanır. İstemciler, koleksiyonun verilerini nasıl depoladığını bilmeden yineleyiciyi kullanır:

BookShelf shelf = new BookShelf(3);
shelf.addBook("Design Patterns");
shelf.addBook("Clean Code");

Iterator<String> iterator = shelf.createIterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

Java'nın yerleşik Iterable ve Iterator arayüzleri tam olarak bu kalıbı izler; bu nedenle Iterable uygulayan herhangi bir sınıfla gelişmiş for döngülerini kullanabilirsiniz. İteratör Kalıbı, birden fazla gezinme yöntemi sağlamanız veya karmaşık iç yapıları istemci kodundan gizlemeniz gerektiğinde temeldir.

challenge icon

Görev

Kolay

Iterator Pattern kullanarak bir çalma listesi sistemi oluşturalım! Şarkıları depolayan ve şarkıların dahili olarak nasıl depolandığını açığa çıkarmadan bunlar arasında sıralı şekilde gezinmek için özel bir iterator sağlayan bir müzik çalma listesi oluşturacaksın. Bu, Iterator Pattern için mükemmel bir kullanım alanıdır ve kullanıcıların koleksiyonunda temiz, tek tip bir arayüz aracılığıyla gezinmesini sağlar.

Kodunu dört dosyaya ayıracaksın:

  • Iterator.java: İki metoda sahip generic Iterator<T> interface'ini Define et: daha fazla öğenin exist olup olmadığını belirten bir boolean döndüren hasNext() ve T türündeki bir sonraki öğeyi döndüren next().
  • Playlist.java: Şarkılarını holds eden Aggregate class'ı Create et. Playlist, şarkıları sabit bir capacity değerine sahip bir String array içinde depolamalı (bu değer constructor'a geçirilir) ve kaç şarkının added olduğunu izlemelidir. Şarkıları çalma listesine eklemek için bir addSong(String song) metodu ekle.

    Playlist'in bir createIterator() metodu olmalıdır; bu metot bir Iterator<String> döndürür. Bunu, PlaylistIterator adlı private bir inner class oluşturarak ve bu sınıfın Iterator interface'ini implements etmesini sağlayarak Implement et. Bu inner iterator kendi index konumunu korur ve songs array'i boyunca gezinerek her şarkıyı sırasıyla döndürür.

  • Song.java: Bir şarkı başlığını saran basit bir Song class'ı Create et. Başlığı (String) alan bir constructor, bir getTitle() metodu ve Playing: [title] döndüren bir toString() metodu olmalıdır.
  • Main.java: Iterator sistemini bir araya getir! Bir input alacaksın: virgülle ayrılmış şarkı başlıkları listesi (örneğin: Bohemian Rhapsody,Stairway to Heaven,Hotel California).

    10 şarkı capacity'sine sahip bir Playlist Create et. Input'u ayrıştır ve her şarkı başlığını çalma listesine add et. Ardından çalma listesinden bir iterator al ve bunu tüm şarkılar arasında gezinmek için kullan; her birini bir Song nesnesiyle sarılmış olarak yazdır (bu nesne Playing: [title] şeklinde görüntülenir).

    Tüm şarkılar arasında iterating yaptıktan sonra yeni bir satıra Playlist complete! yazdır.

Bir input alacaksın: virgülle ayrılmış bir şarkı başlıkları string'i.

Örneğin, input Yesterday,Imagine,Let It Be olduğunda çıktın şöyle olur:

Playing: Yesterday
Playing: Imagine
Playing: Let It Be
Playlist complete!

Main class'ının, temel array yapısı hakkında hiçbir şey bilmeden çalma listesinde gezinmek için iterator'ın hasNext() ve next() metotlarını nasıl kullandığına dikkat et. Iterator, tüm gezinme mantığını encapsulate ederek koleksiyonun dahili gösterimini istemci kodundan gizli tutar!

Kendin dene

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine();
        
        // TODO: 10 şarkı kapasiteli bir Playlist oluştur
        
        // TODO: Girdiyi (virgülle ayrılmış) ayrıştır ve her şarkı başlığını playlist'e ekle
        
        // TODO: createIterator() kullanarak playlist'ten bir iterator elde et
        
        // TODO: Tüm şarkıları dolaşmak için iterator'ı kullan
        // Her şarkı için, onu bir Song nesnesine sar ve yazdır
        
        // TODO: Print "Playlist complete!" after iterating through all songs
    }
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online Java derleyicisi