• 设计模式 | 迭代器模式(iterator)


    定义:

    提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。

    结构:(书中图,侵删)

    一个抽象的聚合类
    若干个具体的聚合类,有一个生成迭代器的方法(相当于实现java的Iterable接口)
    一个抽象的迭代器,定义了迭代所必须的方法
    若干个具体的迭代器
     
    来学习一下java中结构
    《Java编程思想》中,有关集合的类图(应该是java5的,整体结构应该变化不大):

    感觉太复杂了,看起来头疼,自己看源码画了一个和迭代器有关的类图(以ArrayList为例,java8):

    实例:

    就来仿照一个arraylist吧,Iterator接口就不用写了,java已经有了。
    为了简化代码量,List接口还是自己写一个。
    抽象List接口:
    package designpattern.iterator;
    
    import java.util.Iterator;
    
    public interface MyList<E> extends Iterable<E> {// 为了客户端直接通过接口使用foreach方法
        void set(E e, int index);
    
        E get(int index);
    
        void remove(int index);// 数组实现,有点麻烦,就不写了
    
        void changeIterator(Iterator iterator);
    
        int getSize();
    
    }
    ArrayList实现(并不能扩展长度):
    package designpattern.iterator;
    
    import java.util.Iterator;
    
    public class MyArrayList<E> implements MyList<E>, Iterable<E> {
        E[] data;
        private int size;
        Iterator<E> iterator;
    
        public MyArrayList(E[] data) {
            super();
            this.data = data;
            size = data.length;
            iterator = new MyInteratorAsc<>(this);// 默认使用正序迭代器
        }
    
        @Override
        public void set(E e, int index) {
            if (index < size) {
                data[index] = e;
            } else {
                System.out.println(index + "大于数组大小");
            }
        }
    
        @Override
        public E get(int index) {
            return data[index];
        }
    
        @Override
        public Iterator<E> iterator() {
            return iterator;
        }
    
        @Override
        public void remove(int index) {
            throw new UnsupportedOperationException("暂未实现");
        }
    
        @Override
        public int getSize() {
            return size;
        }
    
        @Override
        public void changeIterator(Iterator iterator) {
            this.iterator = iterator;
    
        }
    
    }
    正序迭代器:
    package designpattern.iterator;
    
    import java.util.Iterator;
    
    public class MyInteratorAsc<E> implements Iterator<E> {
        MyList<E> myList;
    
        public MyInteratorAsc(MyList<E> myList) {
            super();
            this.myList = myList;
            this.current = 0;
        }
    
        int current;
    
        @Override
        public boolean hasNext() {
            if (current < myList.getSize()) {
                return true;
            } else {
                return false;
            }
        }
    
        @Override
        public E next() {
            return myList.get(current++);
        }
    
    }
    倒序迭代器:
    package designpattern.iterator;
    
    import java.util.Iterator;
    
    public class MyInteratorDesc<E> implements Iterator<E> {
        MyList<E> myList;
    
        public MyInteratorDesc(MyList<E> myList) {
            super();
            this.myList = myList;
            this.current = myList.getSize() - 1;
        }
    
        int current;
    
        @Override
        public boolean hasNext() {
            if (current >= 0) {
                return true;
            } else {
                return false;
            }
        }
    
        @Override
        public E next() {
            return myList.get(current--);
        }
    }
    客户端:
    package designpattern.iterator;
    
    public class Client {
        public static void main(String[] args) {
            MyList<String> myList = new MyArrayList<>(new String[4]);
            myList.set("", 0);
            myList.set("", 1);
            myList.set("", 2);
            myList.set("", 3);
            myList.set("", 4);
    
            for (String string : myList) {
                System.out.println(string);
            }
    
            System.out.println("-------换成倒序-------");
    
            myList.changeIterator(new MyInteratorDesc<>(myList));
            for (String string : myList) {
                System.out.println(string);
            }
        }
    }
    结果输出:
    4大于数组大小
    鼠
    牛
    虎
    兔
    -------换成倒序-------
    兔
    虎
    牛
    鼠

    总结:

    自己去实现会发现很多的问题,迭代器几乎天天都在用,实在不知道该总结些什么。
    就用书中的原话吧:
    迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。
  • 相关阅读:
    node递归批量重命名指定文件夹下的文件
    nvm
    node在Web中的用途
    给flash续命(rtmp/http-flv网页播放器)
    AMR/PCM格式语音采集/编码/转码/解码/播放
    视频分析,目标跟踪应用方案梳理
    srs-librtmp pusher(push h264 raw)
    srs
    nginx-rtmp/http-flv
    Introduction to Sound Programming with ALSA
  • 原文地址:https://www.cnblogs.com/imoqian/p/10975796.html
Copyright © 2020-2023  润新知