欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-22 21:17:36
定义: 定义: 提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。 结构:(书中图,侵删) 结构:(书中图,侵删) 一个抽象的聚合类 若干个具体的聚合类,有一个生成迭代器的方法(相当于实现java的Iterable接口) 一个抽象的迭代器,定义了迭代所必须的方法 若干个具体的迭 ......

定义:

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

结构:(书中图,侵删)

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

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

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

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

实例:

就来仿照一个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大于数组大小
鼠
牛
虎
兔
-------换成倒序-------
兔
虎
牛
鼠

总结:

自己去实现会发现很多的问题,迭代器几乎天天都在用,实在不知道该总结些什么。
就用书中的原话吧:
迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。