• iterator(迭代器模式)


    迭代器模式

       针对不同的需求,可能需要以不同的方式来遍历整个整合对象,但我们不希望在集合容器的抽象接口层中充斥着各种不同的遍历操作,这
    时候我们就需要一种能完成下面功能的迭代器:
    
    	(1)遍历一个集合对象
    	(2)不需要了解聚合对象的内部结构
    	(3)提供多种不同的遍历方式
    
       迭代器模式提供一种访问集合中的各个元素,而不暴露其内部表示的方法。将在元素之间游走的职责交给迭代器,而不是集合对象,从而简化
    集合容器的实现,让集合容器专注于在它所应该专注的事情上,更加符合单一职责原则。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    UML结构图

    在这里插入图片描述

    1. 迭代器角色(Iterator)提供了在集合容器元素之间游走的方法。
    2. 具体迭代器角色(Concrete Iterator):实现迭代器接口中定义的方法,完成集合的迭代。
    3. 容器角色(Aggregate):抽象容器类,一般是一个接口,提供一个iterator()方法
    4. 具体容器角色(ConcreteAggregate):具体容器类,实现抽象容器类 ,返回该聚合对象的迭代器。

    代码实现

    抽象迭代器

    	package com.lq.Iterator;
    	
    	/**
    	 * @author lq
    	 * @PACKAGE_NAME: com.lq.Iterator
    	 * @CLASS_NAME: Iterator_
    	 * @date 2022/11/9 21:41
    	 * @Description:  迭代器角色(Iterator)提供了在集合容器元素之间游走的方法。
    	 */
    	public interface Iterator_<E> {
    	
    	    boolean hasNext();
    	
    	    E next();
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    抽象容器类

    	package com.lq.Iterator;
    	
    	/**
    	 * @author lq
    	 * @PACKAGE_NAME: com.lq.Iterator
    	 * @CLASS_NAME: Collection_
    	 * @date 2022/11/9 21:42
    	 * @Description:  抽象容器类,一般是一个接口,提供一个iterator()方法
    	 */
    	public interface Collection_<E> {
    	
    	    void add(E o);
    	
    	    int size();
    	
    	    Iterator_ iterator();
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    具体容器类(内部类-- 具体迭代器角色)

    	package com.lq.Iterator;
    	
    	/**
    	 * @author lq
    	 * @PACKAGE_NAME: com.lq.Iterator
    	 * @CLASS_NAME: ArrayList_
    	 * @date 2022/11/9 21:42
    	 * @Description:  具体容器类,实现抽象容器类 ,返回该聚合对象的迭代器。
    	 */
    	public class ArrayList_<E> implements Collection_<E> {
    	
    	    E[] objects = (E[])new Object[10];
    	
    	    //objects中下一个空的位置在哪儿,或者说,目前容器中有多少个元素
    	    private int index = 0;
    	    @Override
    	    public void add(E o) {
    	        if(index == objects.length) {
    	            E[] newObjects = (E[])new Object[objects.length*2];
    	            System.arraycopy(objects, 0, newObjects, 0, objects.length);
    	            objects = newObjects;
    	        }
    	
    	        objects[index] = o;
    	        index ++;
    	    }
    	
    	    @Override
    	    public int size() {
    	        return index;
    	    }
    	
    	    /**
    	     *  调用内部类,好处:自己的迭代器只对自己开放,不能随便调用
    	     */
    	
    	    @Override
    	    public Iterator_<E> iterator() {
    	        return new ArrayListIterator<>();
    	    }
    	
    	    /**
    	     * 具体迭代器角色(Concrete Iterator):实现迭代器接口中定义的方法,完成集合的迭代。
    	     * @param 
    	     */
    	    private class ArrayListIterator<E> implements Iterator_<E> {
    	
    	        private int currentIndex = 0;
    	
    	        @Override
    	        public boolean hasNext() {
    	            if(currentIndex >= index) {
    	                return false;
    	            }
    	            return true;
    	        }
    	
    	        @Override
    	        public E next() {
    	            E o = (E)objects[currentIndex];
    	            currentIndex ++;
    	            return o;
    	        }
    	    }
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    测试

    	package com.lq.Iterator;
    	
    	/**
    	 * @author lq
    	 * @PACKAGE_NAME: com.lq.Iterator
    	 * @CLASS_NAME: Main
    	 * @date 2022/11/9 21:42
    	 * @Description:
    	 */
    	
    	public class Main {
    	    public static void main(String[] args) {
    	        Collection_<String> list = new ArrayList_<>();
    	        for (int i = 0; i < 15; i++) {
    	            list.add("测试 :" + i);
    	        }
    	        System.out.println("长度 :" + list.size());
    	
    	        //这个接口的调用方式:
    	        Iterator_<String> it = list.iterator();
    	        while (it.hasNext()) {
    	            String o = it.next();
    	            System.out.println(o);
    	        }
    	    }
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    结果

    	长度 :15
    	测试 :0
    	测试 :1
    	测试 :2
    	测试 :3
    	测试 :4
    	测试 :5
    	测试 :6
    	测试 :7
    	测试 :8
    	测试 :9
    	测试 :10
    	测试 :11
    	测试 :12
    	测试 :13
    	测试 :14
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    迭代器模式总结

    优点:

    1. 迭代器模式简化了集合的接口,迭代子具备遍历功能,这样集合的接口就不需要重新实现遍历功能。
    2. 每一个聚集对象都可以有一个或多个迭代子对象,每一个迭代子的迭代状态可以是彼此独立的。因此,一个聚集对象可以同时有几个迭代在进行之中。
    3. 由于遍历算法被封装在迭代子角色里面,因此迭代的算法可以独立于聚集角色变化。
    4. 更好的封装性,访问一个集合对象的元素,无需暴露容器内部表示。

    缺点:

    1. 迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
    2. 对于比较简单的遍历,使用迭代器模式显得较为繁琐,比如ArrayList直接就可以用for循环+get() 方法来遍历;
    3. 抽象迭代器的设计难度较大,需要充分考虑到系统将来的扩展,例如JDK内置迭代器Iterator就无法实现逆向遍历,如果需要实现逆向遍历,只能通过其子类ListIterator等来实现,而ListIterator迭代器无法用于操作Set类型的聚合对象。在自定义迭代器时,创建一个考虑全面的抽象迭代器并不是件很容易的事情。

    适用场景:

    1. 访问一个集合对象的内容而无须暴露它的内部表示。
    2. 需要为集合对象提供多种遍历方式。
    3. 为遍历不同的聚合结构提供一个统一的接口。
  • 相关阅读:
    继承day01
    IEEE802.2之LLC(逻辑链路控制)
    荟萃英才教育“破局而立,向新而生”
    「浙江科聪新品发布」新品发布潜伏顶升式移动机器人专用控制器
    【数据结构】链表LinkedList
    cJSON.c 在mfc中编译失败报 lnk2005错误
    用于机器学习的 NumPy(ML)
    山形三元组
    关于在3dsmax中制作的模型导入UE后尺寸大小不对的问题
    等级测评是什么意思?工作流程包含哪些?
  • 原文地址:https://blog.csdn.net/qq_45376284/article/details/127778817