设计模式-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

原文地址:https://www.cnblogs.com/duzhuan/p/13745191.html