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

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

示例程序

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. Picasso 完美兼容 OkHttp3.3,缓存优化两不误

    Tamic 专注移动开发!更多文章请关注http://www.jianshu.com/p/6241950f9daf csdn: http://blog.csdn.net/sk719887916/art ...

  2. 初识gd库

    必备基础 开启GD拓展 列表使用 获取图片信息代码 图片详细信息 特效函数 示例 运行结果 分析 获取图片基本信息 获取图片宽度 获取图片高度 获取图片后缀名 获取图片mime类型 操作图片 添加文字 ...

  3. Dynamics CRM EXCEL导入数据字段类型为选项集时的注意事项

    在开始先展示下CRM的导入数据涉及选项集字段时的一个问题 下图是选项集字段的属性 下图是我要导入的excel中的列值,可以看出列明和字段名是一致的,而列值却不是选项集中已有的选项 在导入校验时,只要字 ...

  4. Android上下文菜单ContentView详解

    ContentView介绍 上下文菜单继承了android.view.Menu,因此我们可以像操作Options Menu那样给上下文菜单增加菜单项.上下文菜单与Options Menu最大的不同在于 ...

  5. 携程React Native实践

    React Native(下文简称 RN)开源已经一年多时间,国内各大互联网公司都在使用,携程也在今年 5 月份投入资源开始引入,并推广给多个业务团队使用,本文将会分享我们遇到的一些问题以及我们的优化 ...

  6. Servlet中的跳转(redirect和forward)

    Forward是通过RequestDispatcher对象的forward(HttpServletRequest request,HttpServletResponse response)方法来实现的 ...

  7. Android开发学习之路--UI之简单聊天界面

    学了很多的ui的知识,这里就来实现个聊天的界面,首先来实现个layout的xml,代码如下: <?xml version="1.0" encoding="utf-8 ...

  8. springMVC 使用ajax 出现No serializer found for class异常

    转自  http://mxdba.iteye.com/blog/668155 google了一下,发现坛子里已经有人解答了 http://godfox.iteye.com/blog/646887 不过 ...

  9. 03 Button 按钮

    按钮   父类: TextView     >概念:可以被按,点击 并且执行一个动作     >属性:         在按钮内部的上下左右设置图片:             androi ...

  10. Linux Debugging(六): 动态库注入、ltrace、strace、Valgrind

    实际上,Linux的调试方法非常多,针对不同的问题,不同的场景,不同的应用,都有不同的方法.很难去概括.本篇文章主要涉及本专栏还没有涵盖,但是的确有很重要的方法.本文主要包括动态库注入调试:使用ltr ...