java集合类中的迭代器模式
不说模式的问题,看一个<<设计模式之禅>>里面的例子。
老板要看到公司了各个项目的情况。(我知道我这个概述很让人头大,看代码吧)
示例程序
v1
package Iterator;
/**
* @author cbf4Life cbf4life@126.com
* 定义一个接口,所有的项目都是一个接口
*/
public interface IProject {
//从老板这里看到的就是项目信息
public String getProjectInfo();
}
package Iterator;
/**
* @author cbf4Life cbf4life@126.com
* 所有项目的信息类
*/
public class Project implements IProject {
//项目名称
private String name = "";
//项目成员数量
private int num = 0;
//项目费用
private int cost = 0;
//定义一个构造函数,把所有老板需要看到的信息存储起来
public Project(String name,int num,int cost){
//赋值到类的成员变量中
this.name = name;
this.num = num;
this.cost=cost;
}
//得到项目的信息
public String getProjectInfo() {
String info = "";
//获得项目的名称
info = info+ "项目名称是:" + this.name;
//获得项目人数
info = info + "\t项目人数: "+ this.num;
//项目费用
info = info+ "\t 项目费用:"+ this.cost;
return info;
}
}
package Iterator;
import java.util.ArrayList;
/**
* @author cbf4Life cbf4life@126.com
* 老板来看项目信息了
*/
public class Boss {
public static void main(String[] args) {
//定义一个List,存放所有的项目对象
ArrayList<IProject> projectList = new ArrayList<IProject>();
//增加星球大战项目
projectList.add(new Project("星球大战项目",10,10));
//增加扭转时空项目
projectList.add(new Project("扭转时空项目",100,1000));
//增加超人改造项目
projectList.add(new Project("超人改造项目",10000,100000));
//这边100个项目
for(int i=4;i<10;i++)
projectList.add(new Project("第"+i+"个项目",i*5,i*100));
//遍历一下ArrayList,把所有的数据都取出
for(IProject project:projectList)
System.out.println(project.getProjectInfo());
}
}
类图如下:
实在太简单了,没什么说的。
不过现在,我想提几个问题。
多个对象聚在一起形成的总体叫做聚集(Aggregate)。在java中就是实现了Collection接口的那些类。我们在学习c的时候就接触的数组就是最最基本的聚集,在java中,数组也是其他聚集类型的设计基础。
从1.2版本开始java就提供了多种聚集,Vector,ArrayList,Stack,LinkList,HashSet,TreeSet,HashMap,TreeMap等等。
数组,堆栈,散列表有多种存储结构,如果我不想有数组来存储工程信息了要换成散列表,上面的代码就得大改(其实,我得承认这个假设本身就有问题,很少会有人没事闲得慌改存储结构,我们只是举个例子,引出我们下面要说的问题)
我们希望,java中的各种聚集都能提供一种"迭代"的功能。
ok 看我们的下个版本
从图中能看到,我们已经使用了jdk提供的迭代器相关模块。
v2
public interface Iterable<T> {
Iterator<T> iterator();
}
Iterable接口,任何能"具有迭代"功能的聚集都要实现这个接口,它也只有一个方法,返回聚集的迭代器。
public interface Iterator<E> {
boolean hasNext();
E next();
void remove();
}
Iterator接口,就是具体的迭代器。
大家在理解迭代器模式的时候,不妨这样想,一个聚集能够遍历自身,之前是因为我们用for循环依次取出每个元素,现在引入了模式后,遍历的功能就交给迭代器这个类(接口)了。
现在看代码
package iterator.v2;
import java.util.ArrayList;
import java.util.Iterator;
/**
* @author cbf4Life cbf4life@126.com
* 定义一个迭代器
*/
public class ProjectIterator implements Iterator<Object>{
//所有的项目都放在这里ArrayList中
private ArrayList<IProject> projectList = new ArrayList<IProject>();
private int currentItem = 0;
//构造函数出入projectList
public ProjectIterator(ArrayList<IProject> projectList){
this.projectList = projectList;
}
//判断是否还有元素,必须实现
public boolean hasNext() {
//定义一个返回值
boolean b = true;
if(this.currentItem>=projectList.size() || this.projectList.get(this.currentItem) == null){
b =false;
}
return b;
}
//取得下一个值
public IProject next() {
return (IProject)this.projectList.get(this.currentItem++);
}
//删除一个对象
public void remove() {
//暂时没有使用到
}
}
package iterator.v2;
import java.util.Iterator;
/**
* @author cbf4Life cbf4life@126.com
* 定义一个接口,所有的项目都是一个接口
*/
public interface IProject extends Iterable<Object>{
//增加项目
public void add(String name,int num,int cost);
//从老板这里看到的就是项目信息
public String getProjectInfo();
public Iterator<Object> iterator();
}
package iterator.v2;
import java.util.ArrayList;
import java.util.Iterator;
/**
* @author cbf4Life cbf4life@126.com
* 所有项目的信息类
*/
@SuppressWarnings("all")
public class Project implements IProject {
//定义一个项目列表,说有的项目都放在这里
private ArrayList<IProject> projectList = new ArrayList<IProject>();
//项目名称
private String name = "";
//项目成员数量
private int num = 0;
//项目费用
private int cost = 0;
public Project(){
}
//定义一个构造函数,把所有老板需要看到的信息存储起来
private Project(String name,int num,int cost){
...
}
//增加项目
public void add(String name,int num,int cost){
this.projectList.add(new Project(name,num,cost));
}
//得到项目的信息
public String getProjectInfo() {
...
}
//产生一个遍历对象
public Iterator<Object> iterator(){
return new ProjectIterator(this.projectList);
}
}
package iterator.v2;
/**
* @author cbf4Life cbf4life@126.com
* 老板来看项目信息了
*/
public class Boss {
public static void main(String[] args) {
//定义一个List,存放所有的项目对象
IProject project = new Project();
//增加星球大战项目
project.add("星球大战项目ddddd",10,100);
//增加扭转时空项目
project.add("扭转时空项目",100,10000);
//增加超人改造项目
project.add("超人改造项目",10000,1000000);
//这边100个项目
for(int i=4;i<14;i++){
project.add("第"+i+"个项目",i*5,i*1000);
}
//遍历一下ArrayList,把所有的数据都取出
ProjectIterator projectIterator = (ProjectIterator) project.iterator();
while(projectIterator.hasNext()){
IProject p = (IProject)projectIterator.next();
System.out.println(p.getProjectInfo());
}
}
}
迭代器模式的通用类图
图里面的具体迭代器与具体聚集之间的关系有点意思,这一点希望大家多看看代码。
另一方面,我们也可以把ProjectIterator作为内部类放置在projcet类里,这样迭代器就能直接访问到projectList。
后面我们这样改了之后再boss类里面
ProjectIterator projectIterator = (ProjectIterator) project.iterator();
代码依然可以用,这就是创建与使用分离的好处,也就是工厂模式的好处。
jdk的迭代器模式在聚集中的应用
uml图
在AbstractList中有以下两个方法
public ListIterator<E> listIterator() {
return new ListItr(0);
}
public Iterator<E> iterator() {
return new Itr();
}
不管是上面的uml图还是下面的代码,大家现在心里一定有个问题,ListItr与Itr是怎么回事。
其实我们只要看看AbstractList的源代码就能明白:Iterator接口里面的方法实在是太少了,hasNext,next,remove就三个方法;从遍历上来说也就是正向遍历,我要是想逆向遍历一下怎么办?ListItr就有这个功能
下面再看一段代码:
import java.util.*;
public class IteratorDemo {
public static void process(Collection c) {
Iterator i = c.iterator(); //创建迭代器对象
//通过迭代器遍历聚合对象
while(i.hasNext()) {
System.out.println(i.next().toString());
}
}
public static void main(String args[]) {
Collection persons;
persons = new ArrayList(); //创建一个ArrayList类型的聚合对象
persons.add("张无忌");
persons.add("小龙女");
persons.add("令狐冲");
persons.add("韦小宝");
persons.add("袁紫衣");
persons.add("小龙女");
process(persons);
}
}
我们现在是用ArrayList来存储数据,要是想换成HashSet很简单,也就
persons = new HashSet<String>(); //创建一个ArrayList类型的聚合对象
一行代码的事。
下面还有一个问题,一个班级(Class in School)包含多个学生(Student),使用Java内置迭代器实现对学生信息的遍历,要求按学生年龄由大到小的次序输出学生信息。
怎么做,这个咱们下一节来讨论。
参考资料
java与模式
设计模式之禅 第二十章 迭代器模式
http://blog.csdn.net/lovelion/article/details/9992005 遍历聚合对象中的元素——迭代器模式 (很多资料都是参考自刘伟老师的博客)
java集合类中的迭代器模式的更多相关文章
- Java集合类中的哈希总结
JAVA集合类中的哈希总结 目 录 1.哈希表 2.Hashtable.HashMap.ConcurrentHashMap.LinkedHashMap.TreeMap区别 3.Hashtable.Ha ...
- Java设计模式系列之迭代器模式
迭代器模式定义 迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示. 迭代器模式的角色构成 (1)迭代器角色(Iterator):定义遍历元素所需 ...
- Java设计模式学习记录-迭代器模式
前言 这次要介绍的是迭代器模式,也是一种行为模式.我现在觉得写博客有点应付了,前阵子一天一篇,感觉这样其实有点没理解透彻就写下来了,而且写完后自己也没有多看几遍,上次在面试的时候被问到java中的I/ ...
- Java笔记20:迭代器模式
迭代器模式 所谓Iterator模式,即是Iterator为不同的容器提供一个统一的访问方式.本文以Java中的容器为例,模拟Iterator的原理. 1 定义一个容器Collection接口 pub ...
- 《JAVA设计模式》之迭代器模式(Iterator)
在阎宏博士的<JAVA与模式>一书中开头是这样描述迭代子(Iterator)模式的: 迭代子模式又叫游标(Cursor)模式,是对象的行为模式.迭代子模式可以顺序地访问一个聚集中的元素而不 ...
- 重学 Java 设计模式:实战迭代器模式「模拟公司组织架构树结构关系,深度迭代遍历人员信息输出场景」
作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 相信相信的力量! 从懵懂的少年,到拿起键盘,可以写一个Hell ...
- Java设计模式8:迭代器模式
迭代器模式 迭代器模式又叫做游标(Cursor)模式,其作用是提供一种方法访问一个容器元素中的各个对象,而又不暴露该对象的内部细节. 迭代器模式结构 迭代器模式由以下角色组成: 1.迭代器角色 负责定 ...
- JAVA集合中的迭代器的遍历
JAVA中的迭代器,迭代实质上就是遍历,在JAVA中使用iterator()方法进行迭代.需要注意的是,iterator()方法的返回值是Iterator对象.Iterator对象有三个方法,hasN ...
- JAVA设计模式之【迭代器模式】
迭代器模式 聚合类,聚合对象 电视机遥控器,迭代器,遍历局和对象中的成员 灵活新增遍历方法 将负责遍历数据的方法提取出来,封装到专门的类中,实现数据存储和数据遍历分离.这就是迭代器模式. 灵活性,可扩 ...
随机推荐
- 全文检索Lucene (2)
接着全文检索Lucene (1) . 下面我们来深入的研究一下,如何使用Lucene! 从全文检索Lucene (1)中我们可以看出,Lucene就好比一个双向的工作流,一方面是对索引库的维护,另一方 ...
- GridView如何适配不同屏幕
GridView和ListView一样,都是项目中常用的控件之一,那么本篇文章要讲的是GridView如何适应不同大小的屏幕,首先,我们来看一张效果图,如下: 每行为四个item,上下左右间距大概2d ...
- Android自定义处理崩溃异常
用过安卓手机的用户以及安卓开发者们会时长碰到程序异常退出的情况,普通用户遇到这种情况,肯定非常恼火,甚至会骂一生垃圾软件,然后卸载掉.那么开发者们在开发过程中遇到这种情况给怎么办呢,当然,你不可能世界 ...
- iOS应用程序工程文件以及启动流程
转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51351188 本文出自:[openXu的博客] iOS程序启动流程 完整启动流程 UIApp ...
- jvm java虚拟机 新生代的配置
1.1.1.1. -Xmn参数 参数-Xmn1m可以用于设置新生代的大小.设置一个较大的新生代会影响老生代的大小,因为这两者的总和是一定的,这个系统参数对于系统性能以及GC行为有很大的影响,新生代一般 ...
- 如何将Ubuntu部署到U盘中,用U盘安装linux操作系统
http://jingyan.baidu.com/article/d5c4b52be79960da560dc59f.html 用U盘装一个linux系统是非常简单的事情,不会就看看这篇文章吧,后期我会 ...
- Zookeeper总概
zookeeper是一个开源的分布式协调服务.是典型的分布式数据一致性的解决方案. zookeeper可以保证以下分布式一致性的特性 1. 顺序性:同一客户端发起的事务请求,最终会严格的按照发出顺序应 ...
- Linux系统调用的实现机制分析
API/POSIX/C库的关系 系统调用的实现 3.1 系统调用处理程序 添加新系统调用 给Linux添加一个新的系统调用是件相对容易的工作.怎样设计和实现一个系统调用是难题所在, ...
- Xcode7.2使用sqlite3数据库的方法
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 之前版本的Xcode是可以直接连接sqlite3的库文件的,但 ...
- Android开发学习之路--UI之ListView
这里再学习写android的ListView,其实我们都使用过ListView,就像手机的联系人,就是用的ListView了.下面就实现下简单的ListView吧,首先是xml文件中添加相关的代码: ...