不说模式的问题,看一个<<设计模式之禅>>里面的例子。

老板要看到公司了各个项目的情况。(我知道我这个概述很让人头大,看代码吧)

示例程序

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集合类中的迭代器模式的更多相关文章

  1. Java集合类中的哈希总结

    JAVA集合类中的哈希总结 目 录 1.哈希表 2.Hashtable.HashMap.ConcurrentHashMap.LinkedHashMap.TreeMap区别 3.Hashtable.Ha ...

  2. Java设计模式系列之迭代器模式

    迭代器模式定义 迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示. 迭代器模式的角色构成 (1)迭代器角色(Iterator):定义遍历元素所需 ...

  3. Java设计模式学习记录-迭代器模式

    前言 这次要介绍的是迭代器模式,也是一种行为模式.我现在觉得写博客有点应付了,前阵子一天一篇,感觉这样其实有点没理解透彻就写下来了,而且写完后自己也没有多看几遍,上次在面试的时候被问到java中的I/ ...

  4. Java笔记20:迭代器模式

    迭代器模式 所谓Iterator模式,即是Iterator为不同的容器提供一个统一的访问方式.本文以Java中的容器为例,模拟Iterator的原理. 1 定义一个容器Collection接口 pub ...

  5. 《JAVA设计模式》之迭代器模式(Iterator)

    在阎宏博士的<JAVA与模式>一书中开头是这样描述迭代子(Iterator)模式的: 迭代子模式又叫游标(Cursor)模式,是对象的行为模式.迭代子模式可以顺序地访问一个聚集中的元素而不 ...

  6. 重学 Java 设计模式:实战迭代器模式「模拟公司组织架构树结构关系,深度迭代遍历人员信息输出场景」

    作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 相信相信的力量! 从懵懂的少年,到拿起键盘,可以写一个Hell ...

  7. Java设计模式8:迭代器模式

    迭代器模式 迭代器模式又叫做游标(Cursor)模式,其作用是提供一种方法访问一个容器元素中的各个对象,而又不暴露该对象的内部细节. 迭代器模式结构 迭代器模式由以下角色组成: 1.迭代器角色 负责定 ...

  8. JAVA集合中的迭代器的遍历

    JAVA中的迭代器,迭代实质上就是遍历,在JAVA中使用iterator()方法进行迭代.需要注意的是,iterator()方法的返回值是Iterator对象.Iterator对象有三个方法,hasN ...

  9. JAVA设计模式之【迭代器模式】

    迭代器模式 聚合类,聚合对象 电视机遥控器,迭代器,遍历局和对象中的成员 灵活新增遍历方法 将负责遍历数据的方法提取出来,封装到专门的类中,实现数据存储和数据遍历分离.这就是迭代器模式. 灵活性,可扩 ...

随机推荐

  1. [ExtJS5学习笔记]第三十四节 sencha extjs 5 grid表格之java后台导出excel

    继上次使用js前端导出excel之后,还有一个主要大家比较关注的是后台实现导出excel,因为本人开发使用的java所以这里使用apache的开源项目poi进行后台excel的导出. 本文目录 本文目 ...

  2. 带你深入理解STL之Set和Map

    在上一篇博客带你深入理解STL之RBTree中,讲到了STL中关于红黑树的实现,理解起来比较复杂,正所谓前人种树,后人乘凉,RBTree把树都种好了,接下来就该set和map这类关联式容器来" ...

  3. Android使用HttpUrlConnection请求服务器发送数据详解

    HttpUrlConnection是java内置的api,在java.net包下,那么,它请求网络同样也有get请求和post请求两种方式.最常用的Http请求无非是get和post,get请求可以获 ...

  4. Effective C++ ——资源管理

    条款13:以对象来管理资源 在C++中我们经常会涉及到资源的申请与申请,一般都是由关键字new 和 delete来操作的,两者都是成对存在的,缺一不可,否则会出现意想不到的问题,例如: class I ...

  5. Android简易实战教程--第二十二话《自定义组合控件模拟qq登录下拉框和其中的一些”小技巧”》

    转载此文章请注明出处:点击打开链接   http://blog.csdn.net/qq_32059827/article/details/52313516 首先,很荣幸此专栏能被CSDN推荐到主页.荣 ...

  6. 18 Loader代码案例

    目录结构: MainActivity.java 代码: package com.qf.day18_loader_demo2; import android.app.Activity; import a ...

  7. 【java虚拟机系列】JVM类加载器与ClassNotFoundException和NoClassDefFoundError

    在我们日常的项目开发中,会经常碰到ClassNotFoundException和NoClassDefFoundError这两种异常,对于经验足够的工程师而言,可能很轻松的就可以解决,但是却不一定明白为 ...

  8. Android 四种常见的线程池

    引入线程池的好处 1)提升性能.创建和消耗对象费时费CPU资源 2)防止内存过度消耗.控制活动线程的数量,防止并发线程过多. 我们来看一下线程池的简单的构造 public ThreadPoolExec ...

  9. ExpandableListView简单应用及listview模拟ExpandableListView

    首先我们还是来看一些案例,还是拿搜狐新闻客户端,因为我天天上下班没事爱看这个东东,上班又没时间看新闻,上下班路途之余浏览下新闻打发时间嘛.           看这个效果挺棒吧,其实实现起来也不难,我 ...

  10. Struts2知识点学习笔记

    写给自己的话 好记性不如烂笔头,不可能说看了一遍视频就可以完全掌握的.留下这篇笔记,便于今后的复习吧. 1. 访问ServletAPI 访问ServletAPI(response,request,)的 ...