说起遍历,我立马就想到for循环,增强for循环,foreach循环这类的循环遍历,这个不错,既然有这么方便的遍历,为什么我们还要学习Iterator这样的遍历呢?

一个重要的理由是:引入Iterator后可以将遍历和实现分离开来

此话怎讲?什么意思呢?

来说明这样的一个场景:

刚开始写程序时,我们用的是Array,我们自定义的时候指定大小,然后用for循环进行遍历的如火如荼,突然有一天,要求变了,数组大小可变,并且要求使用ArrayList来定义这个集合,那么是不是所有的原来定义为Array的集合都需要改变,并改变其遍历方式啊?这样是不是很麻烦了!

那么问题来了,有没有一种方法或者模式,将遍历和实现分开呢?上面的遍历和实现是耦合在一块的,通过for循环来实现遍历,将for循环绑定到遍历上,如果for循环没法实现了(比如上面,Array被ArrayList代替了,那么for循环的长度由length变为size()了),那么遍历就泡汤了。呵呵,当然有这种方法了,那就是Iterator方式了。

怎么把这遍历和实现分离开呢?请看下文详细分解

这里有四个角色,分别是Iterator,CustomeIterator,Aggregate,CustomeAggregate;四个角色,这四个角色对应的不同的用处,具体如下:

Itertor:这个角色是个接口,用来定义顺序逐个遍历元素的API,包含hasNext和next两个方法。

CustomeIterator:这个是实现Iterator的具体类,用来处理实际上的工作,包含了遍历集合必须的信息(需要遍历的集合以及集合对应的下标)

Aggregate:定义创建Iterator的接口API,

CustomeIterator:实现Aggregate接口并制定Iterator实现的具体类CustomeIterator,并将自己指定为CustimeIterator需要的集合

其类图如下所示:

下面是测试案例

1,java util 的Iterator类,这个来自于java.util.Iterator,

2,自定义的BookShelfIterator类

package ModelItertor;

import java.util.Iterator;

public class BookShelfIterator implements Iterator {
private int index;
private BookShelf bookShelf; public BookShelfIterator(BookShelf bookShelf){
this.bookShelf = bookShelf;
this.index = 0;
} public boolean hasNext() {
return index<this.bookShelf.getLength();
} public Object next() {
Book book = this.bookShelf.getBookAt(index);
index++;
return book;
} }

3,Aggregate类

package ModelItertor;
import java.util.Iterator; public interface Aggregate {
public abstract Iterator iterator();
}

Aggregate

4,自定义的BookShelf类

package ModelItertor;

import java.util.Iterator;

public class BookShelf implements Aggregate {

    private Book[] books;
private int last=0;
public BookShelf(int maxsize){
this.books = new Book[maxsize];
} public Book getBookAt(int i){
if(i>=books.length){
return books[books.length-1];
}
else{
return books[i];
}
} public void appendBook(Book book){
books[last] = book;
last++;
} public int getLength(){
return this.last;
} public Iterator iterator() {
return new BookShelfIterator(this);
} }

5,测试的main类

package ModelItertor;
import java.util.Iterator;
public class Main { public static void main(String[] args) {
BookShelf bookShelf = new BookShelf(4);
bookShelf.appendBook(new Book("A"));
bookShelf.appendBook(new Book("B"));
bookShelf.appendBook(new Book("C"));
bookShelf.appendBook(new Book("D"));
Iterator it = bookShelf.iterator();
while(it.hasNext()){
Book book = (Book)it.next();
System.out.println(book.getName());
}
} }

Main

最终结果

A
B
C
D

那么,还是最上面的问题,为什么搞这么复杂呢?

现在有这样的一个需求,书的数量是可变的,也就是集合由以前的Array变为ArrayList,那么,我们只需要修改一下CustomeAggrator类的实现规则即可,对Iterator的类根本不用做任何改变,改变后的BookShelf类如下

package ModelItertor;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; public class BookShelfList implements Aggregate { private List bookList; public BookShelfList(int size){
this.bookList = new ArrayList(size);
} public Book GetBookAt(int i){
return (Book) bookList.get(i);
} public Iterator iterator() {
return new BookShelfListIterator(this);
} public int getLength(){
return bookList.size();
} public void appendBook(Book book){
bookList.add(book);
}
}

测试main方法如下

package ModelItertor;
import java.util.Iterator;
public class Main { public static void main(String[] args) {
BookShelfList booklist = new BookShelfList(2);
booklist.appendBook(new Book("E"));
booklist.appendBook(new Book("F"));
booklist.appendBook(new Book("G"));
booklist.appendBook(new Book("H")); Iterator it2 = booklist.iterator();
while(it2.hasNext()){
Book book = (Book)it2.next();
System.out.println(book.getName());
}
} }

Iterator模式----一个一个遍历的更多相关文章

  1. 【设计模式大法】Iterator模式

    Iterator模式 --一个一个遍历 在Java中的for语句中 i++的作用是让 i 的值在每次循环后自增1,这样就可以访问数组中的下一个元素.下下一个元素.再下下一个元素,也就实现了从头至尾逐一 ...

  2. 1、迭代器 Iterator模式 一个一个遍历 行为型设计模式

    1.Iterator模式 迭代器(iterator)有时又称游标(cursor)是程序设计的软件设计模式,可在容器(container,例如链表或者阵列)上遍访的接口,设计人员无需关心容器的内容. I ...

  3. 290.单词模式。给定一种 pattern(模式) 和一个字符串 str ,判断 str 是否遵循相同的模式。(c++方法)

    题目描述: 给定一种 pattern(模式) 和一个字符串 str ,判断 str 是否遵循相同的模式. 这里的遵循指完全匹配,例如, pattern 里的每个字母和字符串 str 中的每个非空单词之 ...

  4. python excel操作 练习-#操作单列 #操作A到C列 #操作1到3行 #指定一个范围遍历所有行和列 #获取所有行 #获取所有列

    ##操作单列#操作A到C列#操作1到3行#指定一个范围遍历所有行和列#获取所有行#获取所有列 #coding=utf-8 from openpyxl import Workbook wb=Workbo ...

  5. Java 实现迭代器(Iterator)模式

    类图 /** * 自己定义集合接口, 相似java.util.Collection * 用于数据存储 * @author stone * */ public interface ICollection ...

  6. 设计模式之Iterator模式

    STL里的iterator就是应用了iterator模式. 一.什么是迭代模式 Iterator模式也叫迭代模式,是行为模式之一,它把对容器中包含的内部对象的访问委让给外部类,使用Iterator按顺 ...

  7. Java设计模式(12)迭代模式(Iterator模式)

    上了这么多年学,我发现一个问题,好象老师都很喜欢点名,甚至点名都成了某些老师的嗜好,一日不点名,就饭吃不香,觉睡不好似的,我就觉得很奇怪,你的课要是讲的好,同学又怎么会不来听课呢,殊不知:“误人子弟, ...

  8. 设计模式—迭代器Iterator模式

    什么是迭代器模式? 让用户通过特定的接口访问容器的数据,不需要了解容器内部的数据结构. 首先我们先模仿集合中ArrayList和LinkedList的实现.一个是基于数组的实现.一个是基于链表的实现, ...

  9. 设计模式(一)Iterator模式

    Iterator模式用于在数据集合中按照顺序遍历集合.即迭代器模式. 下面来看一段实现了迭代器模式的示例程序. 这段程序的作用是将书(Book)放置到书架(BookShelf)中,并将书的名字按顺序显 ...

随机推荐

  1. ReactNative学习笔记1 Flexbox布局

    一.比例属性flex和布局方向属性flexDirection 例如三个视图的flex属性值分别为2.4.8,则它们的高度比例为2:4:8.,宽度不指定,默认为全屏的宽度. class ZLFReact ...

  2. Linux常用网络带宽监控工具(转)

    本文介绍了一些可以用来监控网络使用情况的Linux命令行工具.这些工具可以监控通过网络接口传输的数据,并测量目前哪些数据所传输的速度.入站流量和出站流量分开来显示. 一些命令可以显示单个进程所使用的带 ...

  3. delphi程序全屏显示无标题栏覆盖整个屏幕

    delphi 简单实现程序全屏显示无标题栏,覆盖整个屏幕,这个在做工控机或屏保时有用的,具体代码如下,感兴趣的朋友可以参考下哈 delphi 程序全屏显示无标题栏,覆盖整个屏幕,这个在做工控机或屏保时 ...

  4. 大白话5分钟带你走进人工智能-第二十节逻辑回归和Softmax多分类问题(5)

                                                        大白话5分钟带你走进人工智能-第二十节逻辑回归和Softmax多分类问题(5) 上一节中,我们讲 ...

  5. Android如何缓存你的BITMAP对象

    在app中通常最占内存.占流量的元素就是图片了,图片往往又无处不在,特别是伴随着list,GridView或者ViewPager出现,这些图片随着你的滑动操作,时而出现在你的屏幕中,时而消失在屏幕之外 ...

  6. frp -- proxy name [ssh] is already in use

  7. kubernetes1.5.2--部署DNS服务

    本文基于kubernetes 1.5.2版本编写 在kubernetes1.2之前,采用skydns+kube2dns+etcd的方式来部署dns.而从1.3开始,则部署方式有了一点儿变化,将skyd ...

  8. 线性判别分析(Linear Discriminant Analysis, LDA)算法初识

    LDA算法入门 一. LDA算法概述: 线性判别式分析(Linear Discriminant Analysis, LDA),也叫做Fisher线性判别(Fisher Linear Discrimin ...

  9. pclint在VS2013中的配置

    1.安装pclint a. 从http://download.csdn.net/detail/finewind/8426979下载破解版的pclint9i版: b. 点击pclint9setuo.ex ...

  10. ambari journalnode异常Can't scan a pre-transactional edit log

    今天在删日志文件,不知道删错哪个地方了. 该目录下一直报错,这个日志文件增长很快, /var/log/hadoop/hdfs/ hadoop-hdfs-journalnode-xx.log 先备份/h ...