Iterator pattern of Java design patterns (15)

To be a human is to settle down and work hard. Others say a few words to you, listen. Scold you a few words, bear it. No one will be used to you like your parents. Keeping your head down is the right way to do things diligently, and being arrogant will only make you waste halfway. You are very young and have no capital to guide you. Oneself is a man, and everyone is heaven; you must continue to enrich yourself if you plan to do things and achieve things in heaven. Only if you are strong enough can you not be trampled by others.

Design pattern learning, I will blog about 23 design patterns in the near future , so stay tuned~
—2021/1/19

definition

Iterator mode (Iterator) provides a way to sequentially access various elements in an aggregate object without exposing the internal representation of the object.

Baidu Encyclopedia

What is iterator

public interface Iterator<E> {
    
    
    /**
     * Returns {@code true} if the iteration has more elements.
     * (In other words, returns {@code true} if {@link #next} would
     * return an element rather than throwing an exception.)
     *
     * @return {@code true} if the iteration has more elements
     */
    boolean hasNext();
    /**
     * Returns the next element in the iteration.
     *
     * @return the next element in the iteration
     * @throws NoSuchElementException if the iteration has no more elements
     */
    E next();
}

Iterator (iterator) is an interface that needs to implement two methods:

  • hasNext(): Is there a next element
  • next(): current element

Iterator (iterator) is often used for data traversal.Usually, it may be used in the map collection.In fact, iterator (iterator) can also be used in the List collection to traverse data.

		ArrayList<String> mList = new ArrayList<>();
        mList.add("张三");
        mList.add("李四");
        mList.add("王五");
        Iterator<String> iterator = mList.iterator();
        //判断有没有下一个元素
        while (iterator.hasNext()) {
    
    
            //输出当前元素 
            Log.i("迭代器模式",iterator.next());
        }

Log图(1.1):
Insert picture description here

ArrayList iterator mode source code analysis

Source code:


    public Iterator<E> iterator() {
    
    
        return new Itr();
    }
  	//Itr为内部类
    private class Itr implements Iterator<E> {
    
    
    
        protected int limit = ArrayList.this.size;
        int cursor;       // 要返回的下一个元素的索引
        int lastRet = -1; // 返回最后一个元素的索引;如果没有,则返回-1
        int expectedModCount = modCount;

        public boolean hasNext() {
    
    
        	//当前下标 < ArrayList集合长度 则返回true 
            return cursor < limit;
        }

		//获取下一个元素
        @SuppressWarnings("unchecked")
        public E next() {
    
    
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            int i = cursor;
            if (i >= limit)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }
    }

ArrayList源码分析图(2.1):
Insert picture description here
In this implementation class, it is implemented to determine whether there is a next element (hasNext()) and what is the current element (next())

next() analysis:

ArrayList源码分析图(2.2):
Insert picture description here
Get the value of the current elementData array in next(), and then judge the length of the array. It can also be seen from this that the bottom layer of ArrayList is an array

Project needs analysis

Suppose that in a school, it is necessary to traverse the current grade and the group of the corresponding class of the current grade.

It is the same as the combination mode requirement.

the difference:

  • Combination mode can be traversed as a single element
  • Iterator mode can traverse arrays and collections through iterators;

Traverse all groups and grades.

UML分析(3.1):
Insert picture description here

  • Red box: Grade
  • Basket: group iterator

The class diagram looks a little more complicated. It doesn't matter. Let's implement the code step by step. After the code is implemented, it will be clear when you look back at the UML class diagram~

Code

The first group of Group01terator (assuming it is stored in an array):

public class Group01terator implements Iterator {
    
    

    //元素数组
    Group[] groups;
    //下标
    int index = 0;

    public Group01terator(Group[] groups) {
    
    
        this.groups = groups;
    }

    /**
     * 判断有无下一个元素
     *
     * @return true有下一个
     */
    @Override
    public boolean hasNext() {
    
    
        //当前下标 > 元素长度  || 当前元素为null 说明没有下一个元素
        if (index >= groups.length || groups[index] == null) {
    
    
            return false;
        } else {
    
    
            //若有下一个元素 当前下标++
            return true;
        }
    }

    /**
     *  返回当前元素
     * @return 当前数组对象
     */
    @Override
    public Object next() {
    
    
        return groups[index++];
    }
}

The second group of Group02terator (assuming it is stored in a collection):

public class Group02terator implements Iterator {
    
    

     //元素数组
    List<Group> list ;
   
    //下标
    int index = 0;

    public Group02terator(List<Group> list) {
    
    
        this.list = list;
    }

    /**
     * 判断有无下一个元素
     *
     * @return true有下一个
     */
    @Override
    public boolean hasNext() {
    
    
        //当前下标 > 元素长度
        if (index > list.size() - 1) {
    
    
            return false;
        } else {
    
    
            //若有下一个元素 当前下标++
            return true;
        }
    }
    
    /**
     *  返回当前元素
     * @return 当前数组对象
     */
    @Override
    public Object next() {
    
    
        return list.get(index++);
    }
}

Classes class interface:

public interface Classes {
    
    
    /**
     * @return 当前具体班级
     */
    public String showClasses();


    /**
     * @param name 具体小组
     */
    public void printGroup(String name);

    /**
     * @return 当前迭代器
     */
    public Iterator createIterator();
}

Classes01 first grade:

public class Classes01 implements Classes {
    
    
    Group[] group;
    /**
     * 数组下标
     */
    int index = 0;

    public Classes01() {
    
    
        group= new Group[5];
        printGroup("雄鹰组");
        printGroup("卧龙组");
        printGroup("凤雏组");
        printGroup("神龟组");
    }

    @Override
    public String showClasses() {
    
    
        return "一年级";
    }

    /**
     * @param name 学生姓名
     */
    @Override
    public void printGroup(String name) {
    
    
        group[index++] = new Group(name);
    }

    @Override
    public Iterator createIterator() {
    
    
        return new Group01terator(group);
    }
}

Introduction to Classes01 rewriting method:

  • showClasses(): Output the current classes
  • printGroup(): Output the current group (4 are initialized in the parameterized structure)
  • createIterator(group[]): Pass the initialized parameters to the Group01terator just written to let him iterate to achieve data traversal

Classes02 second grade:

public class Classes02 implements Classes {
    
    

   List<Group> mlist  =  new ArrayList<Group>();
    /**
     * 数组下标
     */
    int index = 0;

    public Classes02() {
    
    
        printGroup("干饭人组");
        printGroup("Giao组");
        printGroup("神枪手组");
        printGroup("重案八组");
    }

    @Override
    public String showClasses() {
    
    
        return "二年级";
    }

    /**
     * @param name 学生姓名
     */
    @Override
    public void printGroup(String name) {
    
    
        mlist.add(new Group(name));
    }

    @Override
    public Iterator createIterator() {
    
    
        return new Group02terator(mlist);
    }
}

The rewriting methods of Classes02 and Classes01 are the same, so I won't repeat it!

OutPut output results (in order to comply with the Dimit principle (the least know the principle)):

public class OutPut {
    
    

    List<Classes> mlist;

    public OutPut(List<Classes> mlist) {
    
    
        this.mlist = mlist;
    }

    public void printClasses() {
    
    
        Iterator<Classes> iterator = mlist.iterator();
        while (iterator.hasNext()) {
    
    
            Classes next = (Classes) iterator.next();
            Log.i("迭代器模式"," ========"+next.showClasses()+" ========");
            printGroup(next.createIterator());
        }
    }

    /**
     * 输出小组
     * @param iterator 当前实现Iterator的类
     */
    public void printGroup(Iterator iterator){
    
    
        while (iterator.hasNext()) {
    
    
            Group next = (Group) iterator.next();
            Log.i("迭代器模式", next.getName());
        }
    }
}

Here you only need to pass the specific implementation class that implements the Classes interface in the parameterized structure to complete the traversal of all data.

Log(1.2):
Insert picture description here

Role analysis

  • Iterator: Iterator, used to traverse elements
  • Group01terator / Group02terator iterator implementation
  • Classes: Unified aggregation interface, decoupling client and specific aggregation
  • Classes01 / Classes02: unified aggregate interface implementation
  • OutPut: Separate the client from the specific code implementation, in order to comply with the Dimit principle (at least know the principle)

to sum up:

advantage:

  • Support different object traversal
  • In the iterator mode, it is very convenient to add new aggregate classes and iterator classes, without modifying the original code
  • There can be multiple traversals on the same aggregation
  • Will not expose the original code to achieve code traversal

Disadvantages:

  • Since the iterator mode separates the responsibilities of storing data and traversing data, adding new aggregate classes requires corresponding new iterator classes, and the number of classes increases in pairs, which increases the complexity of the system to a certain extent.

Complete code

Go to the Design Patterns/Design Principles homepage

Originality is not easy, your likes are your greatest support for me, remember to like them~

Guess you like

Origin blog.csdn.net/weixin_44819566/article/details/112816640