设计模式之迭代器模式

简介: 对于java的集合容器ArrayList我们都有过输出其数据元素的经历,我们写一个for循环然后遍历输出。然后这样做有一个缺点,那就是我们需要了解ArrayList容器内部的数据结构,比如说里面可能保存的是String或者是Int。现在有一个设计模式叫做迭代器模式,让用户通过特定的接口访问容器的数据,不需要了解容器内部的数据结构。

一、认识迭代器模式


概念:迭代子模式可以顺序的访问集合内部的元素而不必知道集合内部表象。

可能我们会问,集合里面有迭代接口Iterator,为什么还要自己再去设计一个迭代器呢?这不是多此一举嘛。


为此我们先来看看使用迭代器有什么坏处吧。先看下面一段代码:

public class Test {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        //添加元素
        for (int i = 0; i < 5; i++) {
            list.add("index"+i);
        }
        Iterator<String> it = list.iterator();//获取迭代器
        //遍历元素
        while(it.hasNext()) {
            if(it.next().equals("index3")) {
                list.remove(it.next());
            }
        }
    }
}

我们添加5个元素,然后在for循环中去遍历,当遍历到index4的时候,我们移除它。看起来好像代码没有什么问题,但是我们运行一下。你就会发现出现下列错误。

v2-72282bab7f189ed3f7a11196ec6be07e_1440w.jpg

也就是说我们不能在迭代元素的时候进行增删改的操作。而且还有一个重要的原因,那就是我们在迭代元素的时候其实是会有可能修改集合容器中的元素的,这带来了极大的不安全。因为你不知道用户访问这个数据要执行什么操作。于是乎,迭代器模式出现了,能为我们很好的解决上面的问题。


我们来看看迭代模式的类图:

v2-490f6a3ca0b5563133bbc1e095494ec8_1440w.jpg

从上面可以看到这里包含了4个角色,我们分别来介绍一下:


(1)Aggregate集合:创建迭代子的接口; (2)ConcreteAggregate 具体集合:实现迭代子接口; (3)Iterator 迭代子接口:给出迭代每个元素的接口; (4)ConcreteIterator 具体迭代子:实现迭代方法。


我们代码实现一下。


二、代码实现


第一步:定义抽象容器

public abstract class Aggregate {
    //这是我们自己的迭代器
    public abstract MyIterator iterator(); 
    public abstract Object getElement(int index);
    public abstract int size();
}

第二步:定义ConcreteAggregate 具体集合容器

public class ConcreteAggregate extends Aggregate{
    private List<String> list=new ArrayList<>(); 
    public ConcreteAggregate() {
        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.add("赵六");
    }
    @Override
    public MyIterator iterator() {
        return new ConcreteIterator(this);
    } 
    public Object getElement(int index){
        return list.get(index);
    }
    public int size(){
        return list.size();
    }
}

第三步:Iterator 迭代子接口

public interface MyIterator {
    //移动到第一个对象
    public void first();
    //是否最后
    public boolean isLast();
    //移动下一个
    public void next();
    //当前对象
    public Object current();
}

第四步:ConcreteIterator 具体迭代子

public class ConcreteIterator implements MyIterator{
    Aggregate agg;
    int size=0;
    int index=0;    
    public ConcreteIterator(Aggregate agg) {
        this.agg=agg;
        size=agg.size();
    }    
    @Override
    public void first() {
        index=0;   
    }
    @Override
    public boolean isLast() {
        return index>=size;
    }
    @Override
    public void next() {
        if(index<size){
            index++;
        }    
    }
    @Override
    public Object current() {
        return agg.getElement(index);
    }
}

最后我们在客户端调用一下

public class Test {
    public static void main(String[] args) {
        Aggregate agg=new ConcreteAggregate();
        MyIterator iterator = agg.iterator();
        while(!iterator.isLast()){
            System.out.println(iterator.current());
            iterator.next();
        }
    }
}


三、总结


说实话一般情况下,迭代器模式还是很少见的,文章一开始给出了迭代器的缺点,但是我们稍微改变一下就能够避免,也就是说java提供迭代器基本上就能满足我们的要求。还有一点需要注意,迭代器模式适合集合同生共死的。

相关文章
|
24天前
|
设计模式 Java Kotlin
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
41 2
|
1月前
|
设计模式 Java Kotlin
Kotlin - 改良设计模式 - 迭代器模式
Kotlin - 改良设计模式 - 迭代器模式
29 0
|
2月前
|
设计模式 Java 开发者
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
本教程详细讲解Kotlin语法,适合希望深入了解Kotlin的开发者。对于快速学习Kotlin的用户,推荐查看“简洁”系列教程。本文重点介绍迭代器模式,通过具体示例展示了如何在Kotlin中实现迭代器模式,包括使用Iterator、Iterable接口及重载iterator运算符的方法。
34 4
|
2月前
|
设计模式 Java Kotlin
Kotlin学习笔记 - 改良设计模式 - 迭代器模式
Kotlin学习笔记 - 改良设计模式 - 迭代器模式
30 2
|
2月前
|
设计模式 Java 开发者
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
本教程详细讲解了Kotlin中的迭代器模式,包括如何通过实现Iterator和Iterable接口以及重载iterator运算符来实现可遍历的自定义集合。示例展示了如何创建一个图书集类,并通过不同方式使其支持遍历操作,适合希望深入了解Kotlin迭代器模式的开发者。
34 3
|
2月前
|
设计模式 Java Kotlin
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
34 1
|
1月前
|
设计模式 Java Kotlin
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
35 0
|
2月前
|
设计模式 Java Kotlin
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
29 1
|
3月前
|
设计模式 安全 Java
Java设计模式-迭代器模式(21)
Java设计模式-迭代器模式(21)
|
5月前
|
存储 NoSQL Go
iLogtail设计模式问题之迭代器模式是如何应用的
iLogtail设计模式问题之迭代器模式是如何应用的