设计模式之2 iterator模式-主要是容器类的应用

 

容器类是java当中非常重要的类。可以说,基本上每个项目都要用到容器类。通过这个设计模式,主要是反映通过接口来控制提供规定的方法名。具体的实现交给不同的具体的类去实现。collection接口是如此,iterator也是如此。

 

本文word版本(可下载):

 

http://wenku.baidu.com/view/1dc00c6acaaedd3383c4d34a.html

 

首先模拟实现arraylist

package com.bjsxt.dp.iterator;

 

import com.bjsxt.dp.iterator.*;

 

publicclass ArrayListimplements Collection {

    //初始化就是10个对象

    Object[] objects = new Object[10];

    intindex = 0;

    publicvoid add(Object o) {

      

       //如果到达数组上限,就翻倍,并且把原数组里面的所有内容复制到新数组当中

       if(index ==objects.length) {

           Object[] newObjects =new Object[objects.length * 2];

           System.arraycopy(objects, 0, newObjects, 0,objects.length);

          

           //最关键的一步在这里,把老数组的引用指向新数组,那么从arraylist的使用者的角度来说,是看不到内部数组翻倍了。

          

           objects = newObjects;

       }

       objects[index] = o;

       index ++;

    }

   

    publicint size() {

       //返回的是数组当前的index,而不是数组的真实大小

       returnindex;

    }

   

    //向外提供的iterator

    public Iterator iterator() {

      

       returnnew ArrayListIterator();

    }

   

    //通过一个内部类来实现iterator接口。

    privateclass ArrayListIteratorimplements Iterator {

       privateintcurrentIndex = 0;

 

       //目前index的值大于数组的size,就没有下一个了。

       publicboolean hasNext() {

           if(currentIndex >=index)returnfalse;

           elsereturntrue;

       }

 

       //返回当前数组对应的index处的对象,并把游标指向下一个位置

       public Object next() {

           Object o = objects[currentIndex];

           currentIndex ++;

           return o;

       }

      

    }

}

 

通过一个通用的接口,collection

package com.bjsxt.dp.iterator;

 

//通过接口,约束方法的名字

publicinterface Collection {

    void add(Object o);

    int size();

    //指定了容器类必须提供iterator方法,这个方法的返回值是Iterator

    Iterator iterator();

}

 

通过另外一个接口,iterator

package com.bjsxt.dp.iterator;

 

publicinterface Iterator {

    //两个方法,第一是返回一个object对象,第二是看还有没有下一个节点。

    Object next();

    boolean hasNext();

}

 

 

对于linklist,里面放的元素是node

 

package com.bjsxt.dp.iterator;

 

publicclass Node {

    //node的构造方法,传递两个参数,第一是数据本身,第二就是指向下一个节点的next

    public Node(Object data, Node next) {

       super();

       this.data = data;

       this.next = next;

    }

   

    public Object getData() {

       returndata;

    }

    publicvoid setData(Object data) {

       this.data = data;

    }

    public Node getNext() {

       returnnext;

    }

    publicvoid setNext(Node next) {

       this.next = next;

    }

    private Objectdata;

    private Nodenext;

}

 

linkedlist

package com.bjsxt.dp.iterator;

 

import com.bjsxt.dp.iterator.Collection;

 

publicclass LinkedListimplements Collection {

    //第一个节点

    Node head = null;

    //最后一个节点

    Node tail = null;

   

    //大小

    intsize = 0;

   

    //添加项目的方法

    publicvoid add(Object o) {

       //添加的第一个节点  

       Node n = new Node(o,null);

       //只有一个节点的情况,它既是头又是尾

       if(head ==null) {

           head = n;

           tail = n;

       }     

       //每次在最后添加节点,把上一个节点的next指向新添加的节点,并把新节点的next指向null

       //当前tail(也就是现在list当中的最后一个元素)的next指向新节点

       tail.setNext(n);

       //新节点成为新的tail,并且新tailnext自动指向null

       tail = n;

       //同时增大listsize,并且size只在这里变化。

       size ++;

    }

   

    publicint size() {

       //返回的就是当前listsize

       returnsize;

    }

 

    //@Override

    public Iterator iterator() {

       returnnull;

    }

}

 

假设容器当中放的是cat

package com.bjsxt.dp.iterator;

 

publicclass Cat {

    public Cat(int id) {

       super();

       this.id = id;

    }

 

    privateintid;

   

    @Override

    public String toString() {

       return"cat:" +id;

    }

}

 

主类,测试用类。

 

package com.bjsxt.dp.iterator;

 

import com.bjsxt.dp.iterator.ArrayList;

import com.bjsxt.dp.iterator.LinkedList;

 

publicclass Test {

    publicstaticvoid main(String[] args) {

       //ArrayList al = newArrayList();

       //LinkedList al = newLinkedList();

      

      

       //需要灵活的替换容器的类型。

       //体会多态的引用,和灵活的设计模式,一般都是用父类的引用。然后new不同的子类对象。

       //多态,利用父类引用指向子类对象。这里叫做面向接口的编程。

       Collection c = new ArrayList();

       for(int i=0; i<15; i++) {

           c.add(new Cat(i));

       }

       System.out.println(c.size());

      

       //容器的遍历:找到一个统一的遍历方式,事实上,iterator也只是一个接口。

       //接口当中的遍历方法在每个具体的容器类当中实现。

       //需要c提供一个iterator,每个具体的容器类提供不同的iterator。比如arraylist就是ArrayListIterator

      

       //使用来自当前容器的iterator

       Iterator it = c.iterator();

      

       //当我能找到下一个,就把它返回。

       while(it.hasNext()) {

           //next方法返回的是一个object对象。注意这里没有next++方法,也就说,数组游标没有指向下一个。

           //是因为具体的游标实现在每个容器内部,而不是在iterator当中。

           Object o = it.next();

           System.out.print(o +" ");

       }

    }

}

 

 

思想核心:

1.      通过一个通用的接口,collection来限制所有容器都必须实现的方法,方法名必须一致。从而在使用的时候,可以是显示通过父类的对象来指向子类的引用。也就是的多态来访问容器。

2.      每个具体的容器在实现collection当中的方法,自己添加了具体的实现。每个容器实现的方法不一样,但是对容器的使用者test.java来说,看不到内部实现的细节,使用起来都是一样。体现了面向对象的封装,隐藏思想。

3.      为了提供一个统一的遍历,在collection当时提供了iterator方法。那么所有的容器都要去提供iterator.iterator本身是一个接口,这个接口的作用就是用来遍历容器当中的对象。在容器内部,采取了内部类的方式来实现这个接口。对于容器当中每个元素的遍历,每个容器实现的方法都不一样,但是对容器的使用者test.java来说,看不到内部实现的细节,使用起来都是一样。再一次体现了面向对象的封装,隐藏思想。

4.      注意一下iterator当中的两个方法,一个是hasNext(),这个方法的返回值是boolean,也就是说看看容器当中还有没有下一个对象。更重要的是next()方法,它的返回值是一个object对象。注意这里没有next++方法,也就说,数组游标没有指向下一个。是因为具体的游标实现在每个容器内部,而不是在iterator当中。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值