设计模式之迭代器模式

一、java迭代器介绍

1、迭代器接口

在jdk中,与迭代器相关的接口有两个:Iterator 与 Iterable。

Iterator:迭代器,Iterator及其子类通常是迭代器本身的结构与方法;迭代器是一种模式,它可以使得对于序列类型的数据结构的遍历行为与被遍历的对象分离,即我们无需关心该序列的底层结构是什么样子的。只要拿到

这个对象,使用迭代器就可以遍历这个对象的内部。

Iterable:可迭代的,那些想用到迭代器功能的其它类,如AbstractList HashMap等,需要实现该接口。

1)Iterator

Java提供一个专门的迭代器<<interface>>Iterator,我们可以对某个序列实现该interface,来提供标准的Java迭代器。Iterator接口实现后的功能是“使用”一个迭代器。

Package  java.util;
public interface Iterator<E> {
//判断是否存在下一个对象元素
boolean hasNext();
//获得下一个元素
E next();
//移除下一个元素
void remove();
}

 2)Iterable

Java中还提供了一个Iterable接口,Iterable接口实现后的功能是“返回”一个迭代器(Iterator),我们常用的实现了该接口的子接口有: Collection<E>, Deque<E>, List<E>, Queue<E>, Set<E> 等.该接口的iterator()方

法返回一个标准的Iterator实现。

public interface Iterable<T> {
Iterator<T> iterator();
}

2、迭代器的实现

看完源码,我们来看看迭代器是如何使用的:

1) 若类A想要使用迭代器,则它的类声明部分为 class A implement Iterable

2) 在类A实现中,要实现Iterable接口中的唯一方法:Iterator<T> iterator(); 这个方法用于返回一个迭代器,即Iterator接口及其子类;

3) 在类A中,定义一个内部类S,专门用于实现Iterator接口,定制类A自已的迭代器实现。

如下:

    //A实现Iterable接口
class A implement Iterable
{
//该接口返回一个Iterator对象
Iterator<T> iterator() {...}
class S implement Iterator<E>
{
//上面这个对象会有具体实现的方法
boolean hasNext() {....}
E next() {....}
void remove() {....}
}
}

下面我们来看下抽象类AbstractList的jdk源码

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> { // List接口实现了Collection<E>, Iterable<E>   

   protected AbstractList() {
} ...
// 这里返回一个迭代器对象
public Iterator<E> iterator() {
return new Itr();
} // Itr内部类实现迭代器
private class Itr implements Iterator<E> { int cursor = 0;
int lastRet = -1;
int expectedModCount = modCount; // 实现hasNext方法
public boolean hasNext() {
return cursor != size();
}
// 实现next方法
public E next() {
//判断是否有下一个
checkForComodification();
try {
E next = get(cursor);
lastRet = cursor++;
//返回下一个
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
// 实现remove方法
public void remove() {
if (lastRet == -1)
throw new IllegalStateException();
checkForComodification(); try {
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
//判断是否有下一个方法
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
}

3、小案例

//实现Iterable
class ScanAppleStore implements Iterable<String> { ArrayList<String> appleStore = new ArrayList<String>();
//为初始appleStore赋值
ScanAppleStore() {
Collections.addAll(appleStore, "Sweet", "Sour", "Bitter", "litter Sweet", "litter Sour", "litter Bitter");
System.out.print(appleStore);
}
//重写Iterator方法
@Override
public Iterator<String> iterator() {
return new Iterator<String>() {
private int i = 0; public boolean hasNext() {
if (i < appleStore.size()) {
return true;
} else {
return false;
}
} public String next() { return appleStore.get(i++);
} public void remove() {
System.out.print("not defined!");
}
};
} public Iterable<String> reverseIterator() {
return new Iterable<String>() {
public Iterator<String> iterator() {
return new Iterator<String>() {
private int i = appleStore.size() - 1; public boolean hasNext() {
if (i > -1) {
return true;
} else {
return false;
}
} public String next() { return appleStore.get(i--);
} public void remove() {
System.out.print("not defined!");
}
};
}
}; }}

测试类

public class TestIterable {
//构造函数初始化
TestIterable() {
ScanAppleStore appleTree = new ScanAppleStore();
//采用系统自带的迭代器
System.out.println("采用系统自带的迭代器iterator:");
for (String str : appleTree) {
System.out.println(str); }
System.out.println("======================");
System.out.println("采用自己重新迭代器,让相反输出");
//采用自己重新迭代器,让相反输出
for (String str : appleTree.reverseIterator()) {
System.out.println(str);
}
} public static void main(String[] args) {
TestIterable a = new TestIterable(); }
}

运行结果

[Sweet, Sour, Bitter, litter Sweet, litter Sour, litter Bitter]
采用系统自带迭代器iterator:
Sweet
Sour
Bitter
litter Sweet
litter Sour
litter Bitter
======================
采用自己重新迭代器,让相反输出:
litter Bitter
litter Sour
litter Sweet
Bitter
Sour
Sweet

二、迭代器模式

1、什么是迭代器模式

GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。

Iterator模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明的访问集合内部的数据。

2、迭代器模式角色组成

1) 迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口。

  2) 具体迭代器角色(Concrete Iterator):具体迭代器角色要实现迭代器接口,并要记录遍历中的当前位置。

3) 容器角色(Container):容器角色负责提供创建具体迭代器角色的接口。

    4) 具体容器角色(Concrete Container):具体容器角色实现创建具体迭代器角色的接口——这个具体迭代器角色于该容器的结构相关。

3、案例解析

1)迭代器角色

public interface Iterator {
public Object next();
public boolean hasNext();
}

 2)具体迭代器角色

public class ConcreteIterator implements Iterator {

    private List list = new ArrayList();
private int cursor = 0; public ConcreteIterator(List list) {
this.list = list;
} @Override
public Object next() {
Object obj = null;
if (this.hasNext()) {
obj = this.list.get(cursor++);
}
return obj;
} @Override
public boolean hasNext() {
if (cursor == list.size()) {
return false;
}
return true;
}
}

3)容器角色

public interface Aggregate {
public void add(Object obj);
public void remove(Object obj);
public Iterator iterator();
}

4) 具体容器角色

public class ConcreteAggregate implements Aggregate {

    private List list = new ArrayList();  

    @Override
public void add(Object obj) {
list.add(obj);
}
@Override
public void remove(Object obj) {
list.remove(obj);
}
@Override
public Iterator iterator() {
return new ConcreteIterator(list);
}
}

测试类

public class Client {

    public static void main(String[] args) {
Aggregate ag = new ConcreteAggregate();
ag.add("小明");
ag.add("小红");
ag.add("小刚");
Iterator it = ag.iterator();
while (it.hasNext()) {
String str = (String) it.next();
System.out.println(str);
}
}}

运行结果

小明
小红
小刚

4、迭代器优点和缺点

优点

1)它支持以不同的方式遍历一个聚合对象。
    2)迭代器简化了聚合类。
    3)在同一个聚合上可以有多个遍历。 
    4)在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。

缺点

由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。

参考

其实这整篇文章几乎都来自该篇文章,用参考都不太好意思,哈哈。

JAVA迭代器与迭代模式

想太多,做太少,中间的落差就是烦恼。想没有烦恼,要么别想,要么多做。中校【7】

【java设计模式】(6)---迭代器模式(案例解析)的更多相关文章

  1. 16.java设计模式之迭代器模式

    基本需求: 展示一个学校的结构,比如一个学校下面有多个学院,学院下面有多个系,对其节点主要是遍历,与组合模式略有不同 传统方案: 学校<-学院<-系 依次继承 这种方式,在一个页面中展示出 ...

  2. 折腾Java设计模式之迭代器模式

    迭代器模式 Provide a way to access the elements of an aggregate object sequentially without exposing its ...

  3. 简单的了解下Java设计模式:迭代器模式(转载)

    迭代器模式定义 迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示. Java 开发过程中遍历是常用的.如下边程序: for(int i =0 ; ...

  4. java设计模式之迭代器模式

    一.迭代器模式简介 迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 迭代器模式让我们能游走于聚合内的每一个元素,而又不暴露内部的表示.把游走的任务放在迭代器上,而不是 ...

  5. Python进阶:设计模式之迭代器模式

    在软件开发领域中,人们经常会用到这一个概念——“设计模式”(design pattern),它是一种针对软件设计的共性问题而提出的解决方案.在一本圣经级的书籍<设计模式:可复用面向对象软件的基础 ...

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

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

  7. 实践GoF的设计模式:迭代器模式

    摘要:迭代器模式主要用在访问对象集合的场景,能够向客户端隐藏集合的实现细节. 本文分享自华为云社区<[Go实现]实践GoF的23种设计模式:迭代器模式>,作者:元闰子. 简介 有时会遇到这 ...

  8. 【设计模式】Java设计模式 - 享元模式

    Java设计模式 - 享元模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起记录分享自己 ...

  9. Java设计模式——装饰者模式

    JAVA 设计模式 装饰者模式 用途 装饰者模式 (Decorator) 动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator 模式相比生成子类更为灵活. 装饰者模式是一种结构式模式 ...

  10. 浅析JAVA设计模式之工厂模式(一)

    1 工厂模式简单介绍 工厂模式的定义:简单地说,用来实例化对象,取代new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式能够动态决定将哪一个类实例化.不用先知道每次要实例化哪一个类. 工 ...

随机推荐

  1. Shell编程-控制结构 | 基础篇

    if-then-else分支结构 if-then-else是一种基于条件测试结果的流程控制结构.如果测试结果为真,则执行控制结构中相应的命令列表:否则将进行另外一个条件测试或者退出该控制结构. if- ...

  2. Picnic Planning POJ - 1639(最小k度生成树)

    The Contortion Brothers are a famous set of circus clowns, known worldwide for their incredible abil ...

  3. Random Erasing Augmentation(REA)

    为了增强模型的泛化的性能,一般的手段有数据增强和正则化方法(如dropout,BN),而用于数据增强的一般方法有:随机裁剪.随机水平翻转.平移.旋转.增加噪音和生成网络方法等(前两个方法用的最多,也最 ...

  4. FlashFXP用到的功能

    FlashFXP目前用到的个人理解就是: 一个公共空间  大家同时连接进来可以共享文件进去(该软件支持从屏幕上直接拖拽文件进来) 这里面页面之类的可以用手机进行访问(有利于调试) 第一步接收师哥给的软 ...

  5. vue 调用摄像头拍照以及获取相片本地路径(实测有效)

    在学习这个的时候有一点前提:这是针对手机功能的,所以最重要的是要用手机进行实时调试 包含图片的增加和删除功能 <template> <div> <!--照片区域--> ...

  6. 在NSMutableArray中添加空元素:NSNull类的使用

    有时需要将一些表示“空”的对象添加到array中.NSNull类正是基于这样的目的产生的.用NSNull表示一个占位符时,语句表达如下: [array addObject:[NSNull null]] ...

  7. RF无线射频电路设计干货分享

    1.概述:射频(RF)PCB设计,在目前公开出版的理论上具有很多不确定性,常被形容为一种“黑色艺术”.通常情况下,对于微波以下频段的电路(包括低频和低频数字电路),在全面掌握各类设计原则前提下的仔细规 ...

  8. dnmp(docker的lnmp)安装WordPress之后图片上传问题 问题:图片上传大小问题解决和 报错413 Request Entity Too Large

    首先是提示超过图片尺寸和大小, 最后发现都是图片大小的问题, 需要修改php的最大上传size 修改之后查看php配置  已经生效  但是还是报错, 提示返回不是合法的json,  查看控制台, 报错 ...

  9. C++第一课:基本语法for Visual Studio 2015[个人见解]

    在学习C++时,或许不了解情况的人会问:到底先学习C语言还是C++,哪个更好? 那么小编的个人见解是:你在学习时别管哪个语言好与不好,是个语言它都是好语言,关键在于你会挖掘其中存在的价值,C++可以说 ...

  10. Javascript 获取文档元素

    一.getElementById() 参数:id 属性,必须唯一. 返回:元素本身.若 id 不唯一,则返回第一个匹配的元素. 定义的位置:仅 document(即:除 document 之外的元素调 ...