一、模式解析

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


1、迭代子模式一般用于对集合框架的访问,常用的集合框架为list,set,map在实现的时候均可以支持迭代子模式

2、迭代子模式使用同意接口Iterator来完成对象的迭代,一般接口需要实现如下功能:first,next,isDone,currentItem等遍历接口

3、常用的集合框架根据访问需要,可以使用数组,链表等数据结构进行实现,使用迭代子模式可以屏蔽掉数据结构遍历时候产生的差异

4、在java中对结合的增强for循环依赖于迭代子模式实现

二、应用场景

  迭代子模式在实际工作中基本无需自己进行编写,因为使用太过频繁,已经被jdk底层进行实现,所以我们使用集合框架时候直接使用就可以了,在这里,我们需要模拟ArrayList的基本实现和迭代子模式的实现。

  ArrayList的基本结构为:

  1、list内可以存放多个相同类型的元素,

  2、元素可以重复存放

  3、在jdk底层采用数组进行模拟,当存放数据容量超出数组,会对数组进行扩容,自动增加一部分容量,扩容算法为:(this.elementData.length*3)/2+1

  4、继承了Iterator,可以使用迭代器进行遍历

三、场景代码

1、Iterator接口,定义迭代方法

package iterator.example;
/**
* 定义迭代器的接口
* @author zjl
* @time 2016-2-3
*
*/
public interface Iterator<E> {
public E first();
public E next();
public boolean isDone();
public int currentItem();
}

2、定义list接口,为了简化处理,此处直接继承迭代器接口

package iterator.example;

public interface List<E> extends Iterator<E> {
public int size();
public boolean isEmpty();
public E remove(int index);
public int indexOf(E e);
void add(E e);
public E get(int index);
}

3、定义Arraylist,实现各方法

package iterator.example;

import java.util.Arrays;

public class ArrayList<E> implements List<E>{
//初始化一个数组,来保存对象
Object[] elementData;
private int size=0;
//迭代器游标
private int cursor=0;
//数组初始化
public ArrayList(int init){
elementData=new Object[init];
}
//默认构造类型,默认初始化10个元素
public ArrayList(){
this(10);
} @Override
public int size() {
return this.size;
} @Override
public boolean isEmpty() {
return this.size==0;
} @Override
public void add(E e) {
//如果list长度等于数组长度,那么将数组扩大
ensureCapacity(this.size+1);
elementData[this.size++]=e;
} @Override
public E remove(int index) {
RangeCheck(index);
//移除指定位置的元素
E e= (E) elementData[index];
for(;index<this.size;index++){
elementData[index]=elementData[index+1];
}
elementData[index--]=null;
return e;
} @Override
public int indexOf(E e) {
// TODO Auto-generated method stub
return 0;
}
//判断是否超长,如果超长,则扩展数组
public void ensureCapacity(int minCapacity){
int oldCapacity=this.elementData.length;
if(minCapacity>oldCapacity){
int newLength=(this.elementData.length*3)/2+1;
Object[] oldDate=this.elementData;
this.elementData=Arrays.copyOf(elementData, newLength);
} }
private void RangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(
"Index: "+index+", Size: "+size);
}
@Override
public E first() {
return (E) elementData[0];
}
@Override
public E next() {
if(isDone()){
throw new IndexOutOfBoundsException("the list is done");
}
return (E) elementData[cursor++];
}
@Override
public boolean isDone() {
return cursor==size;
}
@Override
public int currentItem() {
// TODO Auto-generated method stub
return cursor;
}
@Override
public E get(int index) {
RangeCheck(index);
return (E) elementData[index];
}
}

4、编写客户端程序

package iterator.example;

public class Client {

    /**
* @param args
*/
public static void main(String[] args) {
List<String> list=new ArrayList<String>();
list.add("java");
list.add("c++");
list.add("python");
list.add("Object-c");
while(!list.isDone()){
System.out.println(list.next());
}
} }

5、执行结果

java
c++
python
Object-c

四、解决差异问题

  此时,虽然可以正常使用迭代器进行循环,但是很明显和jdk中的ArrayList迭代方式不一致,而且无法使用增强循环模式for..in,观察下jdk的实现,我们发现list并没有实现Iterator接口,而是使用了Iterable接口作为过渡,在Iterable中保存了Iterator的引用。

  修改代码为List继承jdk的Iterable,注意,此处必须引用jdk的接口才能增强循环,修改ArrayList代码为,增加方法为:

    @Override
public Iterator<E> iterator() { return new Iterator<E>() {
private int cursor=0;
@Override
public boolean hasNext(){
return cursor!=size;
} @Override
public E next() {
return (E) elementData[cursor++];
}
       //仅仅为了遍历,此方法暂不实现
@Override
public void remove() { } };
}

此时客户端可以使用与原生一样的迭代方法

        Iterator<String> it=list.iterator();
while(it.hasNext()){
System.out.println(it.next());
} for(String s:list){
System.out.println(s);
}

为什么不直接继承Iterator接口,反而使用过渡呢,原因大概如下:

针对集合进行迭代时候,需要使用游标标记当前迭代位置,如果多个位置同时对一个集合进行迭代的话,那么同时需要多个游标来标记当前已经迭代的位置,如果直接继承Iterator接口,那么游标必须保持在集合框架本身,必然造成迭代的冲突,所以使用Iterable,每次开始迭代时候,返回一个Iterator的实现方法,产生一个游标,这样多次迭代不会产生相互冲突。

[工作中的设计模式]迭代子模式Iterator的更多相关文章

  1. [设计模式]迭代子模式 Iterator

    迭代子模式又叫做游标cursor模式,是对象的行为模式.迭代子模式可以顺序的访问一个聚集中的元素而不必暴露聚集的内部表象. 迭代子模式被广泛的应用在Java语言的API中的几个设计模式之一.在Java ...

  2. [工作中的设计模式]备忘录模式memento

    一.模式解析 备忘录对象是一个用来存储另外一个对象内部状态的快照的对象.备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捕捉(Capture)住,并外部化,存储起来,从而可以在将来合适的时候把 ...

  3. java设计模式----迭代子模式

    顺序访问聚集中的对象,主要用于集合中.一是需要遍历的对象,即聚集对象,二是迭代器对象,用于对聚集对象进行遍历访问. 迭代子模式为遍历集合提供了统一的接口方法.从而使得客户端不需要知道聚集的内部结构就能 ...

  4. [工作中的设计模式]享元模式模式FlyWeight

    一.模式解析 Flyweight在拳击比赛中指最轻量级,即“蝇量级”或“雨量级”,这里选择使用“享元模式”的意译,是因为这样更能反映模式的用意.享元模式是对象的结构模式.享元模式以共享的方式高效地支持 ...

  5. [工作中的设计模式]原型模式prototype

    一.模式解析 提起prototype,最近看多了js相关的内容,第一印象首先是js的原型 var Person=function(name){ this.name=name; } Person.pro ...

  6. 设计模式 - 迭代模式(iterator pattern) Java 迭代器(Iterator) 详细解释

    迭代模式(iterator pattern) Java 迭代器(Iterator) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 參考迭代器模式(ite ...

  7. [工作中的设计模式]解释器模式模式Interpreter

    一.模式解析 解释器模式是类的行为模式.给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器.客户端可以使用这个解释器来解释这个语言中的句子. 以上是解释器模式的类图,事实上我 ...

  8. [工作中的设计模式]中介模式模式Mediator

    一.模式解析 用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互. 中介模式又叫调停者模式,他有如下特点: 1.有多个系统或者对 ...

  9. [工作中的设计模式]责任链模式chain

    一.模式解析 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知 ...

随机推荐

  1. HTML案例—很讨巧的一种js+css制作hover模式展示二级菜单方法

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>利 ...

  2. PHP Ajax 跨域问题最佳解决方案

    本文通过设置Access-Control-Allow-Origin来实现跨域. 例如:客户端的域名是client.runoob.com,而请求的域名是server.runoob.com. 如果直接使用 ...

  3. Windows7微软官方原版镜像系统文件

    Windows7微软官方原版镜像系统 Windows 7 是由微软公司(Microsoft)开发的操作系统,核心版本号为Windows NT 6.1.Windows 7可供家庭及 商业工作环境.笔记本 ...

  4. EmguCV控件Emgu.CV.UI.ImageBox及C# picturebox显示图片连续刷新出现闪烁问题

    在上一篇里,EmguCV(OpenCV)实现高效显示汉字及叠加  实现了视频叠加及显示,但存在问题,就是 Emgu.CV.UI.ImageBox及C# picturebox显示图片时都会出现闪烁,尤其 ...

  5. HDFS中JAVA API的使用

    HDFS中JAVA API的使用   HDFS是一个分布式文件系统,既然是文件系统,就可以对其文件进行操作,比如说新建文件.删除文件.读取文件内容等操作.下面记录一下使用JAVA API对HDFS中的 ...

  6. morse code

    morse code,摩斯电码,是一种时通时断的信号代码,通过不同的排列顺序来表达不同的英文字母.数字和标点符号. 摩斯电码,是一种早期的数字化通信形式,但是它不同于现代只使用0和1两种状态的二进制代 ...

  7. JUnit4 中@AfterClass @BeforeClass @after @before的区别对比

    JUnit4使用Java5中的注解(annotation),以下是JUnit4常用的几个annotation: @Before:初始化方法   对于每一个测试方法都要执行一次(注意与BeforeCla ...

  8. 微信"附近的人"新增商家公众号入驻功能

    微信近日升级了“附近的人”,新增商家公众号(认证的服务号和有卡券功能的公众号)可自入驻,这是微信在推出卡券和微信wifi功能后,又一加强连接线下商户能力的功能. 微信在“附近的人”中 增加搜索商户功能 ...

  9. myBatis学习笔记

    java.lang.NullPointerException at cn.itcast.mybatis.dao.UserDaoImpl.findUserById(UserDaoImpl.java:22 ...

  10. linux常用命令-权限管理命令

    chmod  [{ugoa}{+-=}{rwx}] [文件或目录] [mode=421] [文件或目录] -R 递归修改 例:chmod g+w,o-r 文件或目录 但是一般用数字配置权限,例:chm ...