JavaRush /Java Blog /Random-ID /Pola iterator

Pola iterator

Dipublikasikan di grup Random-ID
Hari ini kita akan membahas tentang apa itu Iterator di Java dan mengapa itu diperlukan.
Pola iterator - 1
Seperti yang mungkin sudah Anda ketahui, Java memiliki antarmuka Koleksi luar biasa yang mengimplementasikan antarmuka Iterator. Izinkan saya segera membuat reservasi: antarmuka iterator tidak sama dengan pola iterator di Java! Dan untuk memperjelasnya, pertama-tama mari kita lihat antarmukanya.
Secara harfiah, “Iterator” dapat diterjemahkan sebagai “kekuatan kasar . ” Artinya, ini adalah entitas tertentu yang dapat melakukan iterasi melalui semua elemen dalam koleksi. Selain itu, ini memungkinkan Anda melakukan ini tanpa mempelajari struktur internal dan susunan koleksi.
Mari kita bayangkan sejenak bahwa tidak ada iterator di Java. Dalam hal ini, setiap orang harus menyelami koleksi yang paling dalam dan benar-benar memahami apa yang berbeda ArrayListdari LinkedListdan HashSetdari TreeSet.

Metode yang harus diterapkan Iterator

boolean hasNext()— jika masih ada nilai yang tersisa di objek yang dapat diubah (saat ini merupakan Koleksi), metode akan kembali true, jika tidak ada lagi nilai false. E next()— mengembalikan elemen koleksi berikutnya (objek). Jika tidak ada lagi elemen (tidak ada check hasNext(), dan kami memanggil next()ketika kami mencapai akhir koleksi), metode ini akan throw NoSuchElementException. void remove()- akan menghapus elemen yang terakhir diperoleh oleh next(). Metodenya bisa membuang:
  • UnsupportedOperationException, jika iterator ini tidak mendukung metode ini remove()(misalnya dalam kasus koleksi hanya-baca)
  • IllegalStateException, jika metode tersebut next()belum dipanggil, atau remove()sudah dipanggil sejak panggilan terakhir next().
Jadi, iterator untuk Daftar adalah implementasi yang paling umum. Iterator berpindah dari awal koleksi hingga akhir: ia melihat apakah elemen berikutnya ada dan mengembalikannya jika ada. Sebuah siklus dibangun berdasarkan algoritma sederhana ini for-each. Ekstensinya adalah ListIterator. Mari kita lihat metode iterator daftar Java tambahan. Kemungkinan besar Anda mengenal mereka:
  • void add(E e)— menyisipkan elemen Eke dalam ;List
  • boolean hasPrevious()— akan kembali truejika Listada elemen selama pencarian terbalik;
  • int nextIndex()— akan mengembalikan indeks elemen berikutnya;
  • E previous()— akan mengembalikan elemen sheet sebelumnya;
  • int previousIndex()— akan mengembalikan indeks elemen sebelumnya;
  • void set(E e)- akan mengganti elemen yang dikembalikan oleh panggilan terakhir next()atau previous()dengan elemen e.
Mari kita lihat contoh kecilnya. Mari kita buat yang Listberisi baris-baris ucapan selamat kepada siswa:
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("Обучающимся");
list.add("На");
list.add("JavaRush");
Sekarang kita akan mendapatkan iteratornya dan mencetak semua baris yang ada di konsol:
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}
Sekarang akan ada "hambatan": Koleksi Java, seperti yang mungkin Anda ketahui (dan jika Anda tidak tahu, cari tahu), memperluas antarmuka Iterable, tetapi ini tidak berarti hanya List, Setdan Queuemendukung iterator. For java Map iteratorjuga didukung, tetapi harus dipanggil Map.entrySet():
Map<String, Integer> map = new HashMap<>();
Iterator mapIterator = map.entrySet().iterator();
Kemudian metode tersebut next() akan mengembalikan objek Entryyang berisi pasangan “kunci” – “nilai”. Maka semuanya sama dengan List:
while (mapIterator.hasNext()) {
    Map.Entry<String, Integer> entry = mapIterator.next();
    System.out.println("Key: " + entry.getKey());
    System.out.println("Value: " + entry.getValue());
}
Anda berpikir: “Berhenti. Kita berbicara tentang antarmuka, dan judul artikelnya mengatakan “Pola”. Artinya, pola iterator adalah antarmuka Iterator? Atau apakah antarmuka itu sebuah pola? Jika kata ini pertama kali muncul, saya beri referensi: pola adalah pola desain, perilaku tertentu yang harus dipatuhi oleh suatu kelas atau banyak kelas yang saling berhubungan. Sebuah iterator di java dapat diimplementasikan untuk objek apa pun yang struktur internalnya melibatkan iterasi, dan Anda dapat mengubah tanda tangan dari metode yang sedang dibahas. Hal utama ketika mengimplementasikan suatu pola adalah logika yang harus dipatuhi oleh kelas. Antarmuka iterator adalah implementasi pribadi dari pola dengan nama yang sama, diterapkan pada struktur yang sudah jadi ( List, Set, Queue, Map), dan pada struktur lain, atas kebijaksanaan pemrogram. Dengan memperluas antarmuka Iterator, Anda mengimplementasikan suatu pola, tetapi Anda tidak perlu memperluas antarmuka untuk mengimplementasikan pola tersebut. Analogi sederhananya: semua ikan berenang, tetapi tidak semua yang berenang adalah ikan. Sebagai contoh, saya memutuskan untuk mengambil... kata. Lebih khusus lagi, kata benda. Ini terdiri dari bagian-bagian: awalan, akar, akhiran dan akhir. Untuk bagian dari sebuah kata, kita akan membuat antarmuka WordPartdan kelas yang memperluasnya: 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;
    }
}
Kemudian kelas Word(kata) akan berisi bagian-bagian, dan sebagai tambahannya kita akan menambahkan bilangan bulat yang mencerminkan jumlah bagian dalam kata tersebut:
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;
    }
Oke, kita memiliki empat konstruktor yang kelebihan beban (untuk mempermudah, anggap saja kita hanya dapat memiliki satu sufiks). Sebuah kata benda tidak bisa terdiri dari satu awalan, jadi untuk konstruktor dengan satu parameter kita akan mengatur root. Sekarang mari kita tulis implementasi pola iterator: WordIterator, dengan mengesampingkan 2 metode: hasNext()dan 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--;
        }
    }
}
Yang tersisa hanyalah menugaskan iterator ke kelas Word:
public class Word implements Iterable<Word.WordPart> {@Override
	public Iterator<WordPart>iterator() {
    		return new WordIterator(this);
	}}
Sekarang mari kita lakukan analisis morfemik dari kata “rush”:
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());
        }
    }
}
Harap dicatat bahwa dalam implementasi pola iterator saya, saya memilih urutan keluaran berikut:
  1. akhir
  2. akhiran
  3. menghibur
  4. akar
Saat mendesain iterator sendiri, Anda dapat menentukan algoritma iterasi sesuai keinginan. Semoga sukses dalam studimu!
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION