JAVA之迭代器模式easy come easy go!

来源:互联网 发布:c语言怎么写驱动 编辑:程序博客网 时间:2024/05/20 05:24
迭代器模式是一种大家经常要用到的模式,在JAVA的Collections中大家可以经常应用
最常见的到的是下面这种程序结构
(Iterator i = Object.hasnext;i.next;)
{
 
// to do something;
}

在用这个模式的时候,我们通常就调用这里的方法,而不关心它的内部组织过程,所以让我们来看看它的内在东东。
这里我先给出一个例子。

这个例子是我随便想的,说的是一个山上没有任何的树,现在我们要种植几个树,例如 苹果树什么的,然后我要遍历这些树,给每颗树喷洒不同的农药!
在这个例子中我们可以看到,遍历树的话可以用到迭代器模式!

首先我们要做个迭代器接口,为什么要抽象出来一个接口,(这个问题大家自己网上找接口的好处)!

package TreeIterator;
public interface Iterator {
    
public boolean hasNext();
    
public Object next();
}

这个接口我们有2个方法,hasNext()是否还有下一条数据,next返回具体的Object 这里也就是树。
我们先不必要忙着做他的实现类,我们现在要来做的是这个容器(不是JAVA中容器,与arraylist什么的无关),正所谓树的容器是什么,是山也!
我们想想山应该具有什么呢!?
首先它要有种植树的功能,这里可以看作添加树。我们可以想像山的功能是和树相互关联的,那么他们之间是什么关系呢,我们给他们一

种聚合的关系,聚合的关系大家可以参考UML图,我在这里给出它的一种程序表现形式。


package TreeIterator;

public class Hall {
    Tree[] tree ;         
//这里可以看作是聚合关系
    private int index;   //指向Tree[]的标签
    public Hall(int maxNumber) {
        tree 
= new Tree[maxNumber];
        index 
= 0;
    }

    
public void add(Tree  tree)
    
{
        
this.tree[index]=tree;

        index
++;
    }



    
public Iterator connectIterator()
    
{
        
return new TreeIterator(this);
    }

   
}


这里我们定义的山可以抽象出Hall类来,Tree[]  tree 可以看作是山和树之间的一种聚合关系。add方法就是添加树。问题来了,山

和树有了关系,那么山和迭代器有什么关系呢。它们之间肯定有一种关系。我们有了这个容器(山),就要把这个容器来实现迭代的方法:hasNext()和Next().恩这里我们可以看

出,山和迭代器之间也是一种关联关系。我们就把它看成是一种聚合关系(TIP:聚合关系一种特殊的关联关系)。我们可以通过一个connectIterator方法来链接山和迭代器,接下来

我们要去做一个具体的迭代类,这个具体的类中间有了hasNext()和Next()的具体实现方法


package TreeIterator;

public class TreeIterator implements Iterator{   
   
private int last=0;
    
private Hall hall;
   
    
public TreeIterator(Hall hall) {
        
this.hall=hall;
    }

   
    
public boolean hasNext(){
         
if(last<hall.tree.length)
            
return true;
        
else
            
return false;
    }

   
    
public Tree next(){
        Tree t 
=  hall.tree[last];
        last
++;
        
return t;
    }

}


这里Hall hall 就可以看作是一种关联关系,我们要把山和迭代器联系起来就通过构造函数来实现,hasNext和next实现方法就体现出来了
有了山,有了迭代器,可是树还没有定义,不过这个树的方法还很好解决!树不关联其他的事务,我们可以简单的这么写:

package TreeIterator;

public class Tree {  
    
private String name;
    
public Tree(String name) {
        
this.name=name;
    }

    
public String getName(){
        
return this.name;
    }

}


好了似乎我们整个工程完工了,我们现在来模拟一下农民老大伯来种树撒肥的过程;

package TreeIterator;

public class Pren {

    
public Pren() {
    }

    
public static void main(String[] args){
        Hall hall 
= new Hall(4);
        hall.add(
new Tree("苹果树"));
        hall.add(
new Tree("梨树"));
        hall.add(
new Tree("橘子树"));
        hall.add(
new Tree("凤梨树"));
        
for(Iterator i = hall. connectIterator();i.hasNext();){
            String Type 
= ((Tree)(i.next())).getName();
            
if(Type=="苹果树"){
                System.out.println(
"洒苹果树的农药,");
            }

            
if(Type=="梨树"){
                System.out.println(
"洒梨树的农药");
            }

            
if(Type=="橘子树"){
                System.out.println(
"洒橘子树的农药,洒了也没用,还没到成熟日,现在没结果实");
            }

            
if(Type=="凤梨树"){
               System.out.println(
"南风天,湿气大,让它烂在地里吧");
            }

        }

    }

}

农民的英文单词不记得怎么写了,好像记得是P开头的 ,这里就用Pren 来代替了,首先农民老大伯要有种树的地方,也就是山的实例:Hall hall = new Hall(4); 这座山呢只能

种4个树,山小而五脏俱全,更像一个土包,再要有树才行啊 ,所以4个树的实例出现。好了接下来种树,几毫秒解决!山了有我们就要把山放到迭代器中间去了。遍历这个山(容

器)。

联想
我们看看arrayList中的迭代器模式是怎么实现的!

ArrayList a = new ArrayList();
a.add(
"a1");
a.add(
"a2");
a.add(
"a3");
a.add(
"a4");
for(Iterator i= a.iterator();i.hasNext();)
{
 System.out.println(i.next().toString());
}


是不是很多地方和我们地例子相似!

以上呢是我举出的一个例子,不过这个程序还有很多的不完善的地方!标准的设计模式中呢还有一个Aggregae接口,容器还有实现这个接口来获得具体的迭代器!大家可以参考

JAVA设计模式,我这里没有添加这个接口!还有人要问干脆不做个数组就行了吗!?
呵呵 这个问题大家自己考虑,想想为什么要Vector 为什么要ArrayList;