迭代器模式整理

简介: 迭代器模式整理

一、迭代器模式

1、基础概念

迭代器模式又叫游标模式,是对象的行为模式。迭代器模式可以顺序地访问一个聚集中的元素而不必暴露聚集的内部表象。

2、模式图解

3、核心角色

  • Iterator:迭代器角色

此抽象角色定义出遍历元素所需的接口。

  • ConcreteIterator:具体迭代器角色

此角色实现了Iterator接口,并保持迭代过程中的游标位置。

  • Aggregate:聚集角色

此抽象角色给出创建迭代器(Iterator)对象的接口。

  • ConcreteAggregate:具体聚集角色

聚合持有对象集合,提供返回迭代器的方法,可以正确遍历该集合。

  • Client:客户端角色

持有对聚集及其迭代器对象的引用,调用迭代器对象的迭代接口。

4、源码案例

public class C02_Iterator {
    public static void main(String[] args) {
        //http://www.wityx.com/post/698_1_1.html
        Object[] objArray = {"one","two","three","four","five"};
        Aggregate aggregate = new ConcreteAggregate(objArray);
        Iterator iterator = aggregate.createIterator();
        while (!iterator.isEnd()){
            System.out.println(iterator.currentItem());
            iterator.next();
        }
    }
}
interface Iterator {
    void first();
    void next();
    boolean isEnd();
    Object currentItem();
}
class ConcreteIterator implements Iterator{
    //持有被迭代的聚合对象
    private ConcreteAggregate agg;
    //记录当前迭代索引位置
    private int index = 0;
    //设置当前聚集对象的大小
    private int size = 0;
    public ConcreteIterator (ConcreteAggregate agg){
        this.agg = agg;
        this.size = agg.getSize();
        index = 0;
    }
    @Override
    public void first() {
        index = 0;
    }
    @Override
    public void next() {
        if (index<size){
            index++;
        }
    }
    @Override
    public boolean isEnd() {
        return (index>=size);
    }
    @Override
    public Object currentItem() {
        return agg.getElement(index);
    }
}
abstract class Aggregate {
    // 创建相应迭代器对象的接口
    public abstract Iterator createIterator();
}
class ConcreteAggregate extends Aggregate{
    private Object[] objArray = null;
    public ConcreteAggregate (Object[] objArray){
        this.objArray = objArray;
    }
    @Override
    public Iterator createIterator() {
        return new ConcreteIterator(this);
    }
    public Object getElement (int index){
        if (index<objArray.length){
            return objArray[index];
        } else {
            return null;
        }
    }
    public int getSize (){
        return objArray.length;
    }
}

二、JDK集合应用

1、简单案例

public class C02_ArrayList {
    public static void main(String[] args) {
        List<String> stringList = new ArrayList<>() ;
        stringList.add("One") ;
        stringList.add("Two") ;
        stringList.add("Three") ;
        java.util.Iterator<String> itr = stringList.iterator() ;
        while (itr.hasNext()){
            System.out.println(itr.next());
        }
    }
}

2、Iterator源码

规定了集合迭代的一些方法。

public interface Iterator<E> {
    boolean hasNext();
    E next();
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}

3、ArrayList源码

  • 实现聚合接口List
ArrayList<E> extends AbstractList<E> implements List<E>
  • 内部迭代器接口实现
private class Itr implements Iterator<E> {
    int cursor;
    int lastRet = -1;
    int expectedModCount = modCount;
    Itr() {}
    public boolean hasNext() {}
    public E next() {}
    public void remove() {}
    public void forEachRemaining(Consumer<? super E> consumer) {}
    final void checkForComodification() {}
}
  • 返回迭代器
public Iterator<E> iterator() {
    return new Itr();
}

三、迭代器总结

1、适用场景

迭代器模式是与集合绑定,只要使用集合,就需要同时这个集合的迭代器,以此遍历集合中的数据,java中的容器对象Collection,List、Set、Map都有自己的迭代器。参考http://www.wityx.com/post/698_1_1.html,容器对象在编程语言中十分核心,所以在实现容器的时候基本都有匹配的迭代器,可以满足开发的需要,所以迭代器的自定义实践场景比较少。

2、优点总结

简化集合遍历方式,每一个聚集对象都可以有一个或多个迭代器对象,每一个迭代器的迭代状态可以是彼此独立的。遍历算法被封装在迭代器角色里面,因此迭代的算法可以独立于聚集角色变化。

相关文章
通过 ansible 创建 openstack 虚拟机并部署应用(实战篇)
前文 通过 ansible 创建 openstack 虚拟机并部署应用(配置篇) 接下来我们实战一下。 目录结构 ── ansible.cfg├── group_vars│ ├── all.yml├── openstack.
5820 0
|
存储 Linux Docker
在Docker中,本地的镜像文件都存放在哪里?
在Docker中,本地的镜像文件都存放在哪里?
|
机器学习/深度学习 人工智能 文字识别
一种基于YOLOv8改进的高精度红外小目标检测算法 (原创自研)
【7月更文挑战第2天】 💡💡💡创新点: 1)SPD-Conv特别是在处理低分辨率图像和小物体等更困难的任务时优势明显; 2)引入Wasserstein Distance Loss提升小目标检测能力; 3)YOLOv8中的Conv用cvpr2024中的DynamicConv代替;
1103 4
|
监控 Java Shell
软件体系结构 - 垃圾收集器(3)G1
【4月更文挑战第22天】软件体系结构 - 垃圾收集器(3)G1
113 2
|
缓存 JavaScript 前端开发
一遍关于vue基础语法上篇
一遍关于vue基础语法上篇
120 0
C#由Dictionary赋值引发的对引用类型使用的思考
C#由Dictionary赋值引发的对引用类型使用的思考
|
Java 测试技术
Junit5 - 单元测试框架总结 (基于IntelliJ IDEA)
Junit5 - 单元测试框架总结 (基于IntelliJ IDEA)
344 0
|
Web App开发 JSON 网络协议
Fiddler移动端抓包
本篇文章,博主想使用通俗易懂的话语,让大家明白以下内容: 1. 什么是抓包 2. 哪些场景需要用到抓包 3. Fiddler抓包的原理 4. 怎样使用Fiddler进行移动端抓包
Fiddler移动端抓包
|
移动开发 缓存 运维
技术实践第四期|解读移动开发者日常-性能监控平台应用
应用性能监控平台是用来帮助客户提升应用性能质量和稳定性的重要环节,本人作为一名移动端开发者有着丰富的使用和运维经验,希望通过本文分享过往的心得和使用经验,让我参与开发的U-APM这款产品中,作为借鉴可以在中长期规划中帮助更多的开发者。
技术实践第四期|解读移动开发者日常-性能监控平台应用