• 设计模式-01-Iterator


    一、前言

    参考视频:马士兵-设计模式-Iterator

    参考书目:图解设计模式

    环境:

    • IDEA
    • Maven
    • Junit

    为什么一定要引入Iterator这种复杂的设计模式?

    Iterator模式是用于遍历集合类的bai标准访问方du法。它可以把访问逻辑从不同类型的集合zhi类中抽象出来,从而避免向dao客户端暴露集合的内部结构。
    例如,如果没有使用Iterator,遍历一个数组的方法是使用索引:
    for(int i=0; i<array.size(); i++) { ... get(i) ... }
    而访问一个链表(LinkedList)又必须使用while循环:
    while((e=e.next())!=null) { ... e.data() ... }
    以上两种方法客户端都必须事先知道集合的内部结构,访问代码和集合本身是紧耦合,无法将访问逻辑从集合类和客户端代码中分离出来,每一种集合对应一种遍历方法,客户端代码无法复用。
    更恐怖的是,如果以后需要把ArrayList更换为LinkedList,则原来的客户端代码必须全部重写。
    为解决以上问题,Iterator模式总是用同一种逻辑来遍历集合:
    for(Iterator it = c.iterater(); it.hasNext(); ) { ... }
    奥秘在于客户端自身不维护遍历集合的"指针",所有的内部状态(如当前元素位置,是否有下一个元素)都由Iterator来维护,而这个Iterator由集合类通过工厂方法生成,因此,它知道如何遍历整个集合。
    客户端从不直接和集合类打交道,它总是控制Iterator,向它发送"向前","向后","取当前元素"的命令,就可以间接遍历整个集合。



    二、关系图

    image-20200928155435941



    三、代码

    路径:

    image-20200928145232298

    代码:

    Iterator_:

    package Iterator;
    
    /**
     * @Autord: HuangDekai
     * @Date: 2020/9/28 13:55
     * @Version: 1.0
     * @since: jdk11
     */
    public interface Iterator_ {
        boolean hasNext();
        Object next();
    }
    

    Collection_:

    package Iterator;
    
    /**
     * @Autord: HuangDekai
     * @Date: 2020/9/28 13:59
     * @Version: 1.0
     * @since: jdk11
     */
    public interface Collection_ {
        Iterator_ iterator();
        void add(Object object);
        int Size();
    }
    

    ArrayList_:

    package Iterator;
    
    
    /**
     * @Autord: HuangDekai
     * @Date: 2020/9/28 14:08
     * @Version: 1.0
     * @since: jdk11
     */
    public class ArrayList_ implements Collection_ {
    
        private Object[] objects = new Object[10];
        private int index = 0;
    
        @Override
        public Iterator_ iterator() {
            return new ArrayIterator();
        }
    
        //私有内部类实现ArrayIterator
        private class ArrayIterator implements Iterator_{
            int currentIndex = 0;
    
            @Override
            public boolean hasNext() {
                if (currentIndex >= index) return false;
                return true;
            }
    
            @Override
            public Object next() {
                Object o = objects[currentIndex];
                currentIndex++;
                return o;
            }
        }
    
        @Override
        public void add(Object object) {
            if (index >= objects.length){
                Object[] newObjects = new Object[objects.length*2];
                System.arraycopy(objects,0,newObjects,0,objects.length);
                objects = newObjects;
            }
            objects[index] = object;
            index++;
        }
    
        @Override
        public int Size() {
            return index;
        }
    }
    
    

    LinkedList_

    package Iterator;
    
    /**
     * @Autord: HuangDekai
     * @Date: 2020/9/28 14:52
     * @Version: 1.0
     * @since: jdk11
     */
    public class LinkedList_ implements Collection_{
    
        Node head = null;
        Node tail = null;
        private int size = 0;
    
        private class Node{
            Object data = null;
            Node next = null;
    
            public Node(Object o){
                data = o;
            }
        }
    
        @Override
        public Iterator_ iterator() {
            return new LinkedListIterator();
        }
    
        private class LinkedListIterator implements Iterator_{
    
            private Node currentNode = head;
    
            @Override
            public boolean hasNext() {
                if (currentNode == null) return false;
                return true;
            }
    
            @Override
            public Object next() {
                Object data = currentNode.data;
                currentNode = currentNode.next;
                return data;
            }
        }
    
        @Override
        public void add(Object object) {
            Node node = new Node(object);
            node.next = null;
    
            if (head == null){
                head = node;
                tail = node;
            }
            tail.next = node;
            tail = node;
            size++;
        }
    
        @Override
        public int Size() {
            return size;
        }
    }
    


    四、测试样例

    路径

    image-20200928155149696

    代码

    package Iterator;
    
    import org.junit.Test;
    
    /**
     * @Autord: HuangDekai
     * @Date: 2020/9/28 15:35
     * @Version: 1.0
     * @since: jdk11
     */
    public class IteratorTest {
        @Test
        public void ArrayListTest(){
            Collection_ list = new ArrayList_();
            for (int i = 0; i < 11; i++) {
                list.add(new String("a"+i));
            }
            Iterator_ it = list.iterator();
            while (it.hasNext()){
                System.out.println(it.next());
            }
        }
    
        @Test
        public void LinkedListTest(){
            Collection_ list = new ArrayList_();
            for (int i = 0; i < 11; i++) {
                list.add(new String("b"+i));
            }
            Iterator_ it = list.iterator();
            while (it.hasNext()){
                System.out.println(it.next());
            }
        }
    }
    
    

    可以看到,通过使用迭代器,其实两个测试代码差别只有一行,即不同的Collection_的实现。

    结果:

    image-20200928155220246

  • 相关阅读:
    border-radius的8个属性值_画半圆、叶子等
    CSS的background简写方式(转)
    frameset左右栏锚点定位实例
    HTML5新增
    安装MSI报2503的错误
    当前标识(IIS APPPOOLDefaultWebSite)没有对“C:WindowsMicrosoft.NETFramework64v2.0.50727Temporary ASP.NET Files”的写访问权限 解决方案
    Windows设置相关性AFFINITY,修改使用核心数
    Yaml格式文件处理
    Vs2017离线安装包制作
    Vs2017常用快捷键
  • 原文地址:https://www.cnblogs.com/duzhuan/p/13745191.html
Copyright © 2020-2023  润新知