What is the iterator pattern

The iterator pattern is defined to provide an object that sequentially accesses a series of data in an aggregate object without exposing the internal representation of the aggregate object.

For example, if you take the bus or subway every day, you are lined up one by one, and you don’t need to care about your identity, whether you are male or female, or whatever…

Class diagram:

scenario

Imagine a scenario where there are many books on a shelf and the names need to be displayed in order. Let’s leave aside the fact that Java provides an existing API for the moment. How should we implement it? You can think about it

The primary role of iterators

1. Iterators

In this example, Iterator represents the role of an Iterator, which provides an API. There are two APIS: hasNext to see if the next element exists, and next to get the element.

Public interface Iterator {@return */ Boolean hasNext(); /** * next element * @return */ Object next(); }Copy the code

2. Concretelterators

In this example, the BookShelfIterator represents a concrete Iterator role that implements the Iterator, has a bookShelf to iterate over, and a subscript field that is used to mark the location of the Iterator.

public class BookShelfIterator implements Iterator{ private BookShelf bookShelf; private int index; public BookShelfIterator(BookShelf bookShelf){ this.bookShelf = bookShelf; this.index = 0; } @Override public boolean hasNext() { if (index < bookShelf.getLength()){ return true; }else{ return false; } } @Override public Object next() { Book book = bookShelf.getAt(index); index++; return book; }}Copy the code

3. Aggregate

In this example, an Aggregate is a set of iterator methods that return an instance that implements the iterator interface, that is, an iterator.

Iterator Iterator (); Iterator Iterator (); Iterator Iterator (); }Copy the code

4. ConcreteAggregate

In the example, BookShelf represents a concrete collection that implements Aggregate, a role that implements the iterator iterative method.

public class BookShelf implements Aggregate{ private Book[] books; private int lastIndex = 0; public BookShelf(int maxSize){ this.books = new Book[maxSize]; } public Book getAt(int index){ return books[index]; } public void appendBook(Book book){ this.books[lastIndex] = book; lastIndex++; } public int getLength(){ return lastIndex; } @Override public Iterator iterator() { return new BookShelfIterator(this); }}Copy the code

Other codes:

Entity class

public class Book {

    private String name;

    private String price;
    
    //set get....
}
Copy the code

Mian method test:

public class Main { public static void main(String[] args) { BookShelf bookShelf = new BookShelf(4); Bookshelf. appendBook(new Book(){{setName(" outlaw "); }}); Bookshelf. appendBook(new Book(){{setName(" journey to the West "); }}); Bookshelf.appendbook (new Book(){{setName(" red House "); }}); Bookshelf.appendbook (new Book(){{setName(" romance of three Kingdoms "); }}); Iterator it = bookShelf.iterator(); while (it.hasNext()){ System.out.println(it.next().toString()); }}}Copy the code

After looking at the code above, let’s understand it a little bit more

First, there are four main roles: Two interfaces, two implementations, and the Aggregate interface uses the Iterator interface, so the question is, why do we use it? Let’s look at the Aggregate implementation, which is the BookShelf, and we’re going to iterate over the books on the shelf. So it’s easy to explain why the Aggregate interface uses the Iterator interface. The implementation of the iteration is handed over to the BookShelfIterator, which assigns BookShelf to the BookShelf field in the BookShelfIterator. The BookShelfIterator implements the hasNext and next methods, A sequence of iterations through BookShelf.

The traversal behavior of serial-type data structures is separated from the object being traversed, meaning that we don’t need to care what the underlying structure of the sequence looks like (in this case, the container structure is a set of numbers; in our case, books is an array object). Once you have this object (referring to BookShelf), you can use an iterator to walk through the interior of the object.

Points to consider:

1. Enhance for loops and iterators

  1. The for enhancement is used to process every element in a collection without regard to set subscripts. Simplified Iterator writing.
  2. Enhancement of the for loop has the same effect as iterator traversal, i.e. enhancement of the inner part of the for loop is implemented by calling iteratoer. However, enhancement of the for loop has some disadvantages, such as the inability to dynamically delete the contents of the collection in the enhancement loop, and the inability to obtain subscripts.

2. What scenarios are needed

In daily development, we rarely write our own iterators. Unless you need to customize an iterator corresponding to your own data structure, the apis provided by the open source framework are perfectly adequate.

3. Why so many interfaces

Decoupling, although a concrete class can solve our problems, but is difficult to be used again, in order to weaken the coupling relationship between class and class, we need to introduce a lot of abstract classes and interfaces, another is the abstract thinking is very important, can let be enhanced code maintainability and expansibility, don’t understand it doesn’t matter, we remember all the time. Actually, I don’t really understand, a lot of books say that…

Reference: Graphic Design Patterns