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设计模式之【迭代器模式】
迭代器模式 聚合类,聚合对象 电视机遥控器,迭代器,遍历局和对象中的成员 灵活新增遍历方法 将负责遍历数据的方法提取出来,封装到专门的类中,实现数据存储和数据遍历分离.这就是迭代器模式. 灵活性,可扩 ...
随机推荐
- Dynamics CRM FORM脚本库加载本地脚本
用传统的开发方式,js脚本都是保存在数据库中的,这样也方便迁移,但如果不想存数据库而是存在物理磁盘上,则可通过下述代码,将脚本存放在CRMWEB文件夹的某个路径下,每次都动态引用本地JS. funct ...
- Hibernate通过SQL查询常量时只能返回第一个字符的解决方法
在Hibernate中如果通过 [java] view plaincopy session.createSQLQuery("select '合计' as name from dual&quo ...
- Struts 2 之 OGNL
OGNL概述 Object-Graph Navigation Language,对象图导航语言 1.能够访问对象的方法,如list.size() 2.能够访问静态属性与静态方法,需要在类名前加上@,如 ...
- iOS10软件崩溃 Xcode8崩溃 打印/字体等问题汇总 韩俊强的博客
每日更新关注:http://weibo.com/hanjunqiang 新浪微博!iOS开发者交流QQ群: 446310206 [1].Xcode8代码出现ubsystem: com.apple.U ...
- antlr v4 使用指南连载4——词法规则入门之黄金定律
词法规则入门 黄金定律一二 若输入串能被多个词法规则匹配,那么声明在词法文件最前面的规则生效. parser parser grammar HelloParser; options { languag ...
- 安卓服务Service详解
service(服务)是安卓中的四大组件之一,它通常用作在后台处理耗时的逻辑,与Activity一样,它存在自己的生命周期,也需要在清单文件中配置相关信息,本博客将对Service的各个知识点进行详细 ...
- Google会思考的深度学习系统
上周五在旧金山举行的机器学习会议上,Google软件工程师Quoc V. Le讲解了Google的"深度学习"系统是如何运作的. "深度学习"需要用到大型计算机 ...
- Android初级教程理论知识(第十章Fragment与动画)
Fragment 用途:在一个Activity里切换界面,切换界面时只切换Fragment里面的内容 生命周期方法跟Activity一致,可以理解把其为就是一个Activity 定义布局文件作为Fra ...
- linux下可执行文件的库们
在Linux下有一些命令可以让我们知道可执行文件的很多信息. 记录如下: ldd : print shared library dependencies nm: list symbols from o ...
- Fresco图片框架内部实现原理探索
流行的网络框架 目前流行的网络图片框架: Picasso.Universal Image Loader.Volley的(ImageLoader.NetworkImageView).Glide和Fres ...