2

1. Introduction to iterator mode

1. Problem solved

Mainly solve the problem of traversing the entire collection object.

2. Definition

iterator pattern is a behavioral design pattern that can traverse all elements in the collection without exposing the underlying representation (list, stack, tree, etc.).

3. Application scenarios

  • When there is a complex data structure behind the collection and you want to hide its complexity from the client (for ease of use or safety considerations), you can use the iterator mode.
  • To reduce the repetitive traversal code in the program, you can use the iterator mode.
  • Hope the code can traverse different or even unpredictable data structures, you can use the iterator pattern.

Second, the advantages and disadvantages of the iterator pattern

1. Advantages

  • Single responsibility principle: By extracting huge traversal algorithm codes into independent classes, client code and collections can be organized.
  • The principle of opening and closing: new types of collections and iterators can be implemented and passed to existing code without modifying the existing code.
  • The same collection can be traversed in parallel, because each iterator object contains its own traversal state; at the same time, the traversal can also be paused and continued when needed.

2. Disadvantages

  • If the program only interacts with simple collections, using the iterator pattern may be overkill.
  • For some special collections, using iterators may be less efficient than direct traversal.

3. Application examples of iterator mode: How many QQ friends do you have?

1. Example scenario

The rise of WeChat is the loneliness of QQ. Now there are fewer and fewer people using QQ, but many functions of QQ are still very useful, such as the grouping function of friends, so that you can learn from school, the Internet, work, etc. After separating, how do you know how many QQ friends there are?

Today, take the example of traversing friends in each group to introduce the iterator mode.

2. Implementation of iterator pattern

2.1 Engineering structure
iterator-pattern
└─ src
    ├─ main
    │    └─ java
    │    └─ org.design.pattern.iterator
    │       ├─ model
    │       │    ├─ Friend.java
    │       │    └─ Group.java
    │       └─ tool
    │            ├─ Iterator.java
    │            ├─ Collection.java
    │            └─ impl
    │                 ├─ IteratorImpl.java
    │                 └─ CollectionImpl.java
    └─ test
        └─ java
            └─ org.design.pattern.iterator
                  └─ IteratorTest.java
2.2 Code implementation
2.2.1 Entity class

QQ friends

/**
 * QQ 好友
 */
@Getter
@Setter
@AllArgsConstructor
public class Friend {

    /**
     * 用户id
     */
    private String id;

    /**
     * 昵称
     */
    private String nickname;

    /**
     * 备注
     */
    private String noteName;
}

QQ group

/**
 * QQ 分组
 */
@Setter
@Getter
@AllArgsConstructor
public class Group {

    /**
     * 分组id
     */
    private String id;

    /**
     * 分组名称
     */
    private String name;

    /**
     * 好友列表
     */
    private CollectionImpl<Friend> friendList;

    /**
     * 添加好友
     *
     * @param friend 好友
     * @return boolean
     */
    public boolean addFriend(Friend friend) {
        return friendList.add(friend);
    }

    /**
     * 删除好友
     *
     * @param friend 好友
     * @return boolean
     */
    public boolean removeFriend(Friend friend) {
        return friendList.remove(friend);
    }
}
2.2.2 Tools

iterator interface

/**
 * 迭代器接口
 *
 * @param <T>
 */
public interface Iterator<T> {

    /**
     * 是否有下一个节点
     *
     * @return boolean
     */
    boolean hasNext();

    /**
     * 获取下一个节点
     *
     * @return T
     */
    T getNext();
}

Collection interface

/**
 * 集合接口
 * @param <E>
 */
public interface Collection<E> {

    /**
     * 创建迭代器
     *
     * @return Iterator<E>
     */
    Iterator<E> createIterator();

    /**
     * 添加集合元素
     *
     * @param e 集合元素
     * @return boolean
     */
    boolean add(E e);

    /**
     * 删除集合元素
     *
     * @param e 集合元素
     * @return boolean
     */
    boolean remove(E e);

    /**
     * 获取集合长度
     *
     * @return Integer
     */
    Integer size();

    /**
     * 获取集合元素
     *
     * @param index 索引
     * @return E
     */
    E get(Integer index);
}

Iterator implementation class

/**
 * 迭代器实现类
 *
 * @param <E>
 */
public class IteratorImpl<E> implements Iterator<E> {

    private final CollectionImpl<E> groupCollection;

    private int currentIndex;

    public IteratorImpl(CollectionImpl<E>  groupCollection) {
        this.currentIndex = 0;
        this.groupCollection = groupCollection;
    }

    /**
     * 是否有下一个节点
     *
     * @return boolean
     */
    @Override
    public boolean hasNext() {
        return currentIndex < groupCollection.size();
    }

    /**
     * 获取下一个节点
     *
     * @return E
     */
    @Override
    public E getNext() {
        if (!hasNext()) {
            return null;
        }
        E e = groupCollection.get(currentIndex);
        currentIndex++;
        return e;
    }
}

Collection implementation class

/**
 * 集合实现类
 *
 * @param <E>
 */
public class CollectionImpl<E> implements Collection<E> {

    private final List<E> groupList;

    public CollectionImpl() {
        this.groupList = new ArrayList<>();
    }

    /**
     * 创建迭代器
     *
     * @return Iterator<E>
     */
    @Override
    public Iterator<E> createIterator() {
        return new IteratorImpl<E>(this);
    }

    /**
     * 添加集合元素
     *
     * @param e 集合元素
     * @return boolean
     */
    @Override
    public boolean add(E e) {
        return groupList.add(e);
    }

    /**
     * 删除集合元素
     *
     * @param e 集合元素
     * @return boolean
     */
    @Override
    public boolean remove(E e) {
        return groupList.remove(e);
    }

    /**
     * 获取集合长度
     *
     * @return Integer
     */
    @Override
    public Integer size() {
        return groupList.size();
    }

    /**
     * 获取集合元素
     *
     * @param index 索引
     * @return E
     */
    @Override
    public E get(Integer index) {
        return groupList.get(index);
    }
}
2.3 Test verification
2.3.1 Test verification class
/**
 * 迭代器测试
 */
public class IteratorTest {

    @Test
    public void testIterator() {
        CollectionImpl<Friend> friendCollectionOne = new CollectionImpl<>();
        friendCollectionOne.add(new Friend("1", "小可乐", "王明"));
        friendCollectionOne.add(new Friend("2", "阿毛今天睡醒了", "三毛"));
        friendCollectionOne.add(new Friend("3", "楚语吴歌", "夏亚"));

        CollectionImpl<Friend> friendCollectionTwo = new CollectionImpl<>();
        friendCollectionTwo.add(new Friend("1", "系鞋带进修员 ", "张涛"));

        CollectionImpl<Friend> friendCollectionThree = new CollectionImpl<>();
        friendCollectionThree.add(new Friend("1", "饕餮少女 ", "王霖"));

        CollectionImpl<Group> groupCollection = new CollectionImpl<>();
        groupCollection.add(new Group("1", "同学", friendCollectionOne));
        groupCollection.add(new Group("2", "网友", friendCollectionTwo));
        groupCollection.add(new Group("3", "同事", friendCollectionThree));

        Iterator<Group> groupIterator = groupCollection.createIterator();
        while (groupIterator.hasNext()) {
            Group group = groupIterator.getNext();
            System.out.printf("group id is %s, group name is %s", group.getId(), group.getName());
            System.out.println();
            Iterator<Friend> friendIterator = group.getFriendList().createIterator();
            while (friendIterator.hasNext()) {
                Friend friend = friendIterator.getNext();
                System.out.printf(
                        "Friend nickname is %s, Friend noteName is %s",
                        friend.getNickname(),
                        friend.getNoteName()
                );
                System.out.println();
            }
            System.out.println();
        }
    }
}
2.3.2 Test results
group id is 1, group name is 同学
Friend nickname is 小可乐, Friend noteName is 王明
Friend nickname is 阿毛今天睡醒了, Friend noteName is 三毛
Friend nickname is 楚语吴歌, Friend noteName is 夏亚

group id is 2, group name is 网友
Friend nickname is 系鞋带进修员 , Friend noteName is 张涛

group id is 3, group name is 同事
Friend nickname is 饕餮少女 , Friend noteName is 王霖


Process finished with exit code 0

Four, iterator pattern structure

迭代器模式结构图

  1. Iterator The (Iterator) interface declares the operations required to traverse the collection: get the next element, get the current position, and restart the iteration.
  2. (Concrete Iterators) implement a specific algorithm for traversing a collection. The iterator object must track its own traversal progress. This allows multiple iterators to traverse the same collection independently of each other.
  3. Collection (Collection) interface declares one or more methods to obtain iterators compatible with the collection.

    Note: The type of the return method must be declared as an iterator interface, so that the specific collection can return various types of iterators.

  4. (Concrete Collections) will return a specific concrete iterator entity when the client requests an iterator.
  5. Client (Client) interacts with the two through the interface of collection and iterator. In this way, the client does not need to be coupled to the concrete class, allowing the same client code to use a variety of different collections and iterators

    Clients usually don't create iterators themselves, but get them from the collection. But under certain circumstances, the client can directly create an iterator.

design pattern is not difficult to learn. It itself is a development guiding ideology extracted from years of experience. The key is to practice more and optimize the code with the idea of using design patterns to build more reasonable code.

Source address: https://github.com/yiyufxst/design-pattern-java

Reference materials:
Little Boge re-learned the design pattern: https://github.com/fuzhengwei/itstack-demo-design
In-depth design patterns: https://refactoringguru.cn/design-patterns/catalog


易羽fxst
158 声望5 粉丝