迭代器模式-Iterator

用于访问一个集合中的各个元素, 而又不会暴露集合的内部的细节.

本文展示的例子就是, 在猫群组里, 用迭代器遍历每一只猫.

本文章的例子的继承关系图如下:

其中:

Cat就是猫的定义.

Aggregate是"群组" "集合" 的统一抽象定义.

CatGroup是猫群组.

Iterator是迭代器的接口.

CatGroupIterator是猫群组的迭代器. 用来遍历CatGroup里的每一个Cat.

如果把依赖关系加上的话, 如下:

迭代器接口

统一定义了迭代器该有的方法.

hasNext() 用于判断是否还有下一个元素

next() 用于返回下一个元素, 并且使内部计数器+1

/**
* 迭代器接口
*/
public interface Iterator {
public abstract boolean hasNext(); public abstract Object next();
}

用于生成迭代器的接口

/**
* 该接口中只有一个方法, 这个方法用于生成一个迭代器, 并返回
* <p>
* 如果某个集合想使用迭代器, 那么就就应该实现这个接口
*/
public interface Aggregate {
public abstract Iterator iterator();
}

元素类

本例子中举的是"猫群组"中利用迭代器来遍历每一只猫

所以在创建猫群组之前, 先把"猫类" 定义好

/**
* Cat是个体, 一个Cat实例代表一只猫.
* CatGroup是Cat的集合, 一个CatGroup实例代表一群猫.
*/
public class Cat {
private int age;
private String name; public Cat(String name, int age) {
this.age = age;
this.name = name;
} @Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
}

集合类

接下来创建"猫群组"类

猫群组类想要使用迭代器的话, 需要先实现Aggregate接口的iterator()方法, 来获提供群组的迭代器.

/**
* Cat是个体, 一个Cat实例代表一只猫.
* CatGroup是Cat的集合, 一个CatGroup实例代表一群猫.
*
* 并且这个类实现了Aggregate的iterator()方法来获取迭代器
*/
public class CatGroup implements Aggregate { private int last;
private Cat[] cats; public CatGroup(int maxsize) {
this.cats = new Cat[maxsize];
} public Cat getByIndex(int index) {
return cats[index];
} public void append(Cat cat) {
cats[last++] = cat;
} public int getLength() {
return last;
} @Override
public Iterator iterator() {
return new CatGroupIterator(this);
}
}

集合迭代器类

接下来介绍猫群组的迭代器.

hasNext() 用于判断猫群组里是否还有下一只猫. 如果 index 小于 猫群组中猫的个数, 那么肯定有下一只; 否则, 肯定没有下一只猫, 表示已经遍历完所有猫了

next()方法负责直接返回"下一只猫" 并且把计数器+1.

public class CatGroupIterator implements Iterator {
private int index;
private CatGroup catGroup; public CatGroupIterator(CatGroup catGroup) {
this.catGroup = catGroup;
this.index = 0;
} @Override
public boolean hasNext() {
return index < catGroup.getLength();
} @Override
public Object next() {
return catGroup.getByIndex(index++);
}
}

测试

public class Main {
public static void main(String[] args) {
// 创建一个猫群
CatGroup catGroup = new CatGroup(20); // 向猫群里添加猫
catGroup.append(new Cat("betty", 10));
catGroup.append(new Cat("nancy", 11));
catGroup.append(new Cat("wood", 14));
catGroup.append(new Cat("zira", 18)); // 获取遍历该猫群的迭代器
Iterator iterator = catGroup.iterator(); // 迭代并输出
while (iterator.hasNext()) {
Cat c = (Cat) iterator.next();
System.out.println(c);
}
}
}

这段代码的github地址: https://github.com/GoldArowana/design-patterns/tree/master/src/main/java/com/king/patterns/iterator

总结

为什么使用迭代器, 而不是使用数组+下角标的方法来遍历数组呢?

因为这样就可以把遍历一个集合的api进行统一. 无论是数组还是链表或者是其他集合, 都可以用迭代器来进行统一调用.

也就是说Iterator把一个集合的实现和遍历进行了分离.

迭代器模式-Iterator(Java实现)的更多相关文章

  1. Java 设计模式系列(十五)迭代器模式(Iterator)

    Java 设计模式系列(十五)迭代器模式(Iterator) 迭代器模式又叫游标(Cursor)模式,是对象的行为模式.迭代子模式可以顺序地访问一个聚集中的元素而不必暴露聚集的内部表象(interna ...

  2. 设计模式(十):从电影院中认识"迭代器模式"(Iterator Pattern)

    上篇博客我们从醋溜土豆丝与清炒苦瓜中认识了“模板方法模式”,那么在今天这篇博客中我们要从电影院中来认识"迭代器模式"(Iterator Pattern).“迭代器模式”顾名思义就是 ...

  3. 迭代器模式 Iterator 行为型 设计模式(二十)

    迭代器模式(Iterator)   走遍天下,世界那么大,我想去看看   在计算机中,Iterator意为迭代器,迭代有重复的含义,在程序中,更有“遍历”的含义 如果给定一个数组,我们可以通过for循 ...

  4. 设计模式学习--迭代器模式(Iterator Pattern)和组合模式(Composite Pattern)

    设计模式学习--迭代器模式(Iterator Pattern) 概述 ——————————————————————————————————————————————————— 迭代器模式提供一种方法顺序 ...

  5. 设计模式 - 迭代器模式(iterator pattern) 具体解释

    迭代器模式(iterator pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 迭代器模式(iterator pattern) : 提供一 ...

  6. 设计模式系列之迭代器模式(Iterator Pattern)——遍历聚合对象中的元素

    模式概述 模式定义 模式结构图 模式伪代码 模式改进 模式应用 模式在JDK中的应用 模式在开源项目中的应用 模式总结 说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修 ...

  7. 设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型)

      设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型) 1.概述 类中的面向对象编程封装应用逻辑.类,就是实例化的对象,每个单独的对象都有一个特定的身份和状态.单独的对象是一种组织代码的 ...

  8. 乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern)

    原文:乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern) 作者:weba ...

  9. 二十四种设计模式:迭代器模式(Iterator Pattern)

    迭代器模式(Iterator Pattern) 介绍提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示. 示例有一个Message实体类,某聚合对象内的各个元素均为该实体对象,现 ...

随机推荐

  1. wxPython的简单应用

  2. SQLServer之PRIMARY KEY约束

    PRIMARY KEY约束添加规则 1.在表中常有一列或多列的组合,其值能唯一标识表中的每一行,这样的一列或多列成为表的主键(PrimaryKey). 2.一个表只能有一个主键,而且主键约束中的列不能 ...

  3. 通过指令码来判断Java代码的执行顺序(++问题与return和finally的问题)

    问题 在<深入理解Java虚拟机>一书中遇到了如下代码: public int method() { int i; try { i = 1; return i; } catch (Exce ...

  4. C++中 #if 和 #ifdef 区别

    以#开头的都是预编译指令,就是在正式编译之前,编译器做一些预处理的工作#if 条件语句程序段1 //如果条件语句成立,那么就编译程序段1#endif程序段2//如果条件不语句成立,那么就编译程序段2# ...

  5. CORS——跨域请求那些事儿

    在日常的项目开发时会不可避免的需要进行跨域操作,而在实际进行跨域请求时,经常会遇到类似 No 'Access-Control-Allow-Origin' header is present on th ...

  6. Linux运维高级-核心知识提高

    一.Linux之定时任务crond 二.Linux之用户管理 三.Linux之初识磁盘 四.Linux之磁盘管理 五.Linux三剑客-SED 六.Linux三剑客-AWK 七.初识shell编程 八 ...

  7. 手把手教你实现Android RecyclerView上拉加载功能

    摘要 一直在用到RecyclerView时都会微微一颤,因为一直都没去了解怎么实现上拉加载,受够了每次去Github找开源引入,因为感觉就为了一个上拉加载功能而去引入一大堆你不知道有多少BUG的代码, ...

  8. identity server4 证书

    我们需要对token进行签名, 这意味着identity server需要一对public和private key. 幸运的是, 我们可以告诉identity server在程序的运行时候对这项工作进 ...

  9. exgcd

    int exgcd(int a,int b,int &x,int &y){ if (b==0){ x=1,y=0; return a; } int d=exgcd(b,a%b,y,x) ...

  10. 将docker镜像上传到docker hub