设计模式学习(十八):迭代器模式

设计模式,学习,十八,迭代,模式 · 浏览次数 : 33

小编点评

**设计模式学习(十八):迭代器模式** **概述** 迭代器模式是一种行为型模式,用于遍历容器中的元素,并根据元素的添加或删除时间戳实现快照功能。 **主要概念** * ** Collection_<E> 接口:**定义了一个容器的接口,包含大小方法、添加方法和迭代器方法。 * ** Iterator_<E> 接口:**定义了一个迭代器接口,包含 hasNext 和 next 方法,用于获取容器中的元素并进行遍历。 * ** ArrayListIterator_<E>:**实现了 Collection_<E> 接口的具体实现类,它是一个内部类,用于存储和管理 ArrayList 的元素。 **代码示例** ```java public class ArrayList_<E> implements Collection_<E> { private E[] objects = (E[]) new Object[10]; private int index = 0; @Override public int size() { return index; } @Override public void add(E element) { if (objects.length == size()) { // 满了就扩容为原来的两倍 E[] newObjects = (E[]) new Object[objects.length * 2]; arraycopy(objects, 0, newObjects, 0, objects.length); objects = newObjects; } objects[index] = element; index++; } @Override public Iterator_<E> iterator() { return new ArrayListIterator_<>(); } private class ArrayListIterator_<E> implements Iterator_<E> { private int currentIndex = 0; @Override public boolean hasNext() { return currentIndex < index; } @Override public E next() { E o = (E) objects[currentIndex]; currentIndex++; return o; } } } ``` **快照迭代器** 当元素被加入到集合中的时候,我们将 `addTimestamp` 设置为当前时间,将 `delTimestamp` 设置成最大长整型值(`Long.MAX_VALUE`)。当元素被删除时,我们将 `delTimestamp` 更新为当前时间,表示已经被删除。 **总结** 迭代器模式允许在不复制容器的情况下实现快照操作,通过存储元素添加和删除时间的戳来记录元素的创建和删除时间。

正文

设计模式学习(十八):迭代器模式

作者:Grey

原文地址:

博客园:设计模式学习(十八):迭代器模式

CSDN:设计模式学习(十八):迭代器模式

迭代器模式

迭代器模式是一种行为型模式。

迭代器最典型的应用是容器遍历

image

模仿 JDK 的容器,我们自定义一个容器并实现 iterator 方法;

首先,我们先定义一个容器接口

public interface Collection_<E> {
    int size();

    void add(E element);

    Iterator_<E> iterator();
}

里面包括了一个 iterator 方法,所以每个实现这个容器接口的具体容器类型,都必须自定义 iterator 方法, 然后定义一个 Iterator 接口 Iterator_, 具体容器中可以增加一个内部类来专门实现这个接口,

比如我们的具体容器类是 ArrayList_

import static java.lang.System.arraycopy;

public class ArrayList_<E> implements Collection_<E> {
    private E[] objects = (E[]) new Object[10];
    private int index = 0;

    @Override
    public int size() {
        return index;
    }

    @Override
    public void add(E element) {
        if (objects.length == size()) {
            // 满了就扩容为原来的两倍
            E[] newObjects = (E[]) new Object[objects.length * 2];
            arraycopy(objects, 0, newObjects, 0, objects.length);
            objects = newObjects;
        }
        objects[index] = element;
        index++;
    }

    @Override
    public Iterator_<E> iterator() {
        return new ArrayListIterator_<>();
    }

    private class ArrayListIterator_<E> implements Iterator_<E> {
        private int currentIndex = 0;

        @Override
        public boolean hasNext() {
            return currentIndex < index;
        }

        @Override
        public E next() {
            E o = (E) objects[currentIndex];
            currentIndex++;
            return o;
        }
    }

}

我们主要看 ArrayListIterator_这个内部类,里面其实是实现了 Iterator_ 这个接口,所以 ArrayList_ 的遍历操作会执行这个内部类中的操作规则来对其进行遍历。

如何实现一个快照迭代器

我们可以在容器中,为每个元素保存两个时间戳,一个是添加时间戳 addTimestamp,一个是删除时间戳 delTimestamp。

当元素被加入到集合中的时候,我们将 addTimestamp 设置为当前时间,将 delTimestamp 设置成最大长整型值(Long.MAX_VALUE)。

当元素被删除时,我们将 delTimestamp 更新为当前时间,表示已经被删除。

注意,这里只是标记删除,而非真正将它从容器中删除。

同时,每个迭代器也保存一个迭代器创建时间戳 snapshotTimestamp,也就是迭代器对应的快照的创建时间戳。

当使用迭代器来遍历容器的时候,只有满足

addTimestamp < snapshotTimestamp < delTimestamp

的元素,才是属于这个迭代器的快照。如果元素的

addTimestamp > snapshotTimestamp

说明元素在创建了迭代器之后才加入的,不属于这个迭代器的快照;

如果元素的

delTimestamp < snapshotTimestamp

说明元素在创建迭代器之前就被删除掉了,也不属于这个迭代器的快照。

这样就在不拷贝容器的情况下,在容器本身上借助时间戳实现了快照功能。

迭代器模式应用

  • MyBatis 中的 DefaultCursor

它实现了 Cursor 接口,而且定义了一个成员变量 cursorIterator,其定义的类型为 CursorIterator 。继续查看 CursorIterator 类的源码实现,它是 DefaultCursor 的一个内部类,并且实现了 JDK 中的 Iterator 接口。

UML 和 代码

UML 图

代码

更多

设计模式学习专栏

参考资料

与设计模式学习(十八):迭代器模式相似的内容:

设计模式学习(十八):迭代器模式

设计模式学习(十八):迭代器模式 作者:Grey 原文地址: 博客园:设计模式学习(十八):迭代器模式 CSDN:设计模式学习(十八):迭代器模式 迭代器模式 迭代器模式是一种行为型模式。 迭代器最典型的应用是容器遍历 模仿 JDK 的容器,我们自定义一个容器并实现 iterator 方法; 首先,

设计模式学习(十):门面模式

设计模式学习(十):门面模式 作者:Grey 原文地址: 博客园:设计模式学习(十):门面模式 CSDN:设计模式学习(十):门面模式 门面模式 门面模式是一种结构型模式。 门面模式为子系统提供一组统一的接口,定义一组高层接口让子系统更易用。 假设建造一个房子需要有如下三个步骤: 第一步,和泥 第二

设计模式学习(十一):组合模式

设计模式学习(十一):组合模式 作者:Grey 原文地址: 博客园:设计模式学习(十一):组合模式 CSDN:设计模式学习(十一):组合模式 组合模式 组合模式是一种结构型模式。 组合模式中,最常用的一个用法就是目录层级的遍历,话不多说,直接上代码,主方法中 public class Main {

设计模式学习(十二):享元模式

设计模式学习(十二):享元模式 作者:Grey 原文地址: 博客园:设计模式学习(十二):享元模式 CSDN:设计模式学习(十二):享元模式 享元模式 享元模式是一种结构型模式。 一个应用场景是:运用共享技术有效地支持大量细粒度的对象。主要解决 在有大量对象时,有可能会造成内存溢出,我们把其中共同的

设计模式学习(十三):观察者模式

设计模式学习(十三):观察者模式 作者:Grey 原文地址: 博客园:设计模式学习(十三):观察者模式 CSDN:设计模式学习(十三):观察者模式 观察者模式 观察者模式是一种行为型模式。在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。 一般可以用做事件处理

设计模式学习(十四):模板方法

设计模式学习(十四):模板方法 作者:Grey 原文地址: 博客园:设计模式学习(十四):模板方法 CSDN:设计模式学习(十四):模板方法 模板方法 模板方法是一种行为型模式。 假设我们要实现一个游戏,这个游戏有「初始化」,「启动」,「结束」三个方法,那么可以定义一个游戏的模板: public a

设计模式学习(十五):策略模式

设计模式学习(十五):策略模式 作者:Grey 原文地址: 博客园:设计模式学习(十五):策略模式 CSDN:设计模式学习(十五):策略模式 策略模式 策略模式是一种行为型模式,它定义了一组算法,将每个算法都封装起来,并且使它们之间可以互换。 以实例来说明 假设我们有一个猫类,这个类里面有体重和身高

设计模式学习(十六):责任链模式

设计模式学习(十六):责任链模式 作者:Grey 原文地址: 博客园:设计模式学习(十六):责任链模式 CSDN:设计模式学习(十六):责任链模式 责任链模式 责任链模式是一种行为型模式。 举例说明:有一段文本需要过滤一系列敏感字,我们可以通过责任链模式来设计这个功能,假设文本是 scripts H

设计模式学习(十七):状态模式

设计模式学习(十七):状态模式 作者:Grey 原文地址: 博客园:设计模式学习(十七):状态模式 CSDN:设计模式学习(十七):状态模式 状态模式 状态模式是一种行为型模式。 对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。 举例说明: Person 有 Cry ,

设计模式学习(十九):访问者模式

设计模式学习(十九):访问者模式 作者:Grey 原文地址: 博客园:设计模式学习(十九):访问者模式 CSDN:设计模式学习(十九):访问者模式 访问者模式 访问者模式是一种行为型模式。 访问者模式在结构不变的情况下动态改变对于内部元素的动作。 举例说明: 假设我们需要构造一台电脑,有主板( Bo