Chinaunix首页 | 论坛 | 博客
  • 博客访问: 337326
  • 博文数量: 31
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1134
  • 用 户 组: 普通用户
  • 注册时间: 2013-08-25 09:41
个人简介

目前任职于搜狐~

文章分类

全部博文(31)

文章存档

2014年(12)

2013年(19)

分类: Java

2014-02-21 01:26:05

迭代器模式属于GOF提出的23种设计模式之一,GOF对它的定义是:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。它是一种只应用于容器对象遍历的设计模式,比如我们自己定义了一种数据结构,就可以让它实现Iterable接口,用迭代器的方式来遍历这种自定义数据结构。迭代器模式比较简单也不太受到大家的关注。在我们平常的开发过程中,可能经常会用到java为我们封装好的容器迭代器的遍历方式,比如遍历ArrayList我们可以用for循环遍历,也可以用Iterator的遍历。iterator()是Iterable接口所包含的方法,Collection接口继承了Iterable接口,所以所有实现Collection接口的容器都可以直接使用迭代器的方式来遍历。由于java已经为我们对容器对象做了很好的封装,我们平时其实很少会自己实现迭代器模式。
我们通过自己手工实现一个简单的ArrayList和LinkedList容器,来为大家描述一下迭代器模式的具体使用。
第一步:手工实现一个简单的ArrayList 和 LinkedList容器
1、第一个文件:Collection接口

点击(此处)折叠或打开

  1. public interface Collection {

  2.     /**
  3.      * 添加元素
  4.      * @param o
  5.      */
  6.     public void add(Object o);
  7.     
  8.     /**
  9.      * 返回大小
  10.      * @return
  11.      */
  12.     public int size();
  13.     
  14.     /**
  15.      * 迭代方法
  16.      * @return
  17.      */
  18.     public Iterator iterator();
  19. }
2、第二个文件:MyArrayList容器实现类

点击(此处)折叠或打开

  1. public class MyArrayList implements Collection {

  2.     /**
  3.      * List成员
  4.      */
  5.     private Object[] elementData;
  6.     
  7.     /**
  8.      * List长度
  9.      */
  10.     private int size;

  11.     /**
  12.      * 构造方法
  13.      * @param elementData
  14.      * @param size
  15.      */
  16.     public MyArrayList(int size) {
  17.         super();
  18.         this.elementData = new Object[size];
  19.         this.size = 0;
  20.     }
  21.     
  22.     public MyArrayList(){
  23.         this(10); //默认创建容器长度为10
  24.     }
  25.     
  26.     /**
  27.      * 添加元素
  28.      */
  29.     public void add(Object o){
  30.         if(this.size >= 10){
  31.             int newSize = size * 3;
  32.             elementData = Arrays.copyOf(elementData, newSize);
  33.         }
  34.         elementData[size] = o;
  35.         size++;
  36.     }
  37.     
  38.     /**
  39.      * 返回容器长度
  40.      * @return
  41.      */
  42.     public int size(){
  43.         return size;
  44.     }
  45.     
  46.     public Object get(int size){
  47.         return elementData[size];
  48.     }
  49. }
3、第三个文件:LinkedList实现类

点击(此处)折叠或打开

  1. public class MyLinkedList implements Collection{

  2.     /**
  3.      * 头结点
  4.      */
  5.     private Node head = null;
  6.     
  7.     /**
  8.      * 当前大小
  9.      */
  10.     private int size = 0;
  11.     
  12.     /**
  13.      * 尾节点
  14.      */
  15.     private Node tail = null;
  16.     
  17.     /**
  18.      * 添加元素
  19.      * @param o
  20.      */
  21.     public void add(Object o){
  22.         Node node = new Node(o,null);
  23.         if(head == null){ //如果头结点为空
  24.             head = node;
  25.             tail = node;
  26.             node.setNext(null);
  27.         }else{
  28.             tail.setNext(node);
  29.             tail = node;
  30.         }
  31.         size++;
  32.     }
  33.     
  34.     /**
  35.      * 获取长度
  36.      * @return
  37.      */
  38.     public int size(){
  39.         return size;
  40.     }
  41. }
4、第四个文件:Node实体类

点击(此处)折叠或打开

  1. public class Node {

  2.     /**
  3.      * 链表数据本身
  4.      */
  5.     private Object data;
  6.     
  7.     /**
  8.      * 指向链表下一个元素
  9.      */
  10.     private Node next;

  11.     public Node(Object data, Node next) {
  12.         super();
  13.         this.data = data;
  14.         this.next = next;
  15.     }

  16.     public Object getData() {
  17.         return data;
  18.     }

  19.     public void setData(Object data) {
  20.         this.data = data;
  21.     }

  22.     public Node getNext() {
  23.         return next;
  24.     }

  25.     public void setNext(Node next) {
  26.         this.next = next;
  27.     }
  28. }
5、第五个文件:测试Main方法

点击(此处)折叠或打开

  1. /**
  2.  * 测试Main方法
  3.  */
  4. public class TestMain {

  5.     public static void main(String [] args){
  6.         Collection c1 = new MyArrayList();
  7.         for(int i=0;i<5;i++){
  8.             Object o = new Object();
  9.             System.out.println("序号:" + i + " 对象:" + o);
  10.             c1.add(o);
  11.         }
  12.         
  13.         Collection c2 = new MyLinkedList();
  14.         for(int i=0;i<5;i++){
  15.             Object o = new Object();
  16.             System.out.println("序号:" + i + " 对象:" + o);
  17.             c2.add(o);
  18.         }
  19.     }
  20. }

好了,写到这里我们就简单实现了两个容器对象,大家可以想一个问题:如何没有迭代器模式,那我们要如何遍历这两种容器呢?答案是只能通过for循环的方式来遍历,但基于数组实现的ArrayList和基于链表实现的LinkedList的遍历方式肯定是不一样的,如果我们的系统有一个需求原来是基于ArrayList实现的,现在要替换成LinkedList来实现,那是不是很多遍历的方法都要修改?这个时候我们就可以考虑使用迭代器模式了,迭代器模式的功能就是为我们提供一种通用的容器遍历方式,下面我们将迭代器模式加入到工程中去。
第二步:迭代器模式的具体实现
1、第一个文件:迭代器模式接口Iterator.java

点击(此处)折叠或打开

  1. public interface Iterator {

  2.     /**
  3.      * 返回下一个对象
  4.      * @return
  5.      */
  6.     Object next();
  7.     
  8.     /**
  9.      * 是否还有下一个元素
  10.      * @return
  11.      */
  12.     boolean hasNext();
  13.     
  14. }
2、第二个文件:ArrayList实现类

点击(此处)折叠或打开

  1. public class MyArrayList implements Collection {

  2.     /**
  3.      * List成员
  4.      */
  5.     private Object[] elementData;
  6.     
  7.     /**
  8.      * List长度
  9.      */
  10.     private int size;

  11.     /**
  12.      * 构造方法
  13.      * @param elementData
  14.      * @param size
  15.      */
  16.     public MyArrayList(int size) {
  17.         super();
  18.         this.elementData = new Object[size];
  19.         this.size = 0;
  20.     }
  21.     
  22.     public MyArrayList(){
  23.         this(10); //默认创建容器长度为10
  24.     }
  25.     
  26.     /**
  27.      * 添加元素
  28.      */
  29.     public void add(Object o){
  30.         if(this.size >= 10){
  31.             int newSize = size * 3;
  32.             elementData = Arrays.copyOf(elementData, newSize);
  33.         }
  34.         elementData[size] = o;
  35.         size++;
  36.     }
  37.     
  38.     /**
  39.      * 返回容器长度
  40.      * @return
  41.      */
  42.     public int size(){
  43.         return size;
  44.     }
  45.     
  46.     public Object get(int size){
  47.         return elementData[size];
  48.     }
  49.     
  50.     public Iterator iterator(){
  51.         return new ArrayListIterator();
  52.     }
  53.     
  54.     /**
  55.      * 迭代器的内部类实现
  56.      */
  57.     private class ArrayListIterator implements Iterator{

  58.         private int currentIndex = 0;
  59.         
  60.         @Override
  61.         public boolean hasNext() {
  62.             // TODO Auto-generated method stub
  63.             if(currentIndex >= size)return false;
  64.             else return true;
  65.         }


  66.         @Override
  67.         public Object next() {
  68.             // TODO Auto-generated method stub
  69.             Object o = elementData[currentIndex];
  70.             currentIndex++;
  71.             return o;
  72.         }
  73.     }
  74. }
3、第三个文件:LinkedList实现类

点击(此处)折叠或打开

  1. public class MyLinkedList implements Collection{

  2.     /**
  3.      * 头结点
  4.      */
  5.     private Node head = null;
  6.     
  7.     /**
  8.      * 当前大小
  9.      */
  10.     private int size = 0;
  11.     
  12.     private Node tail = null;
  13.     
  14.     /**
  15.      * 添加元素
  16.      * @param o
  17.      */
  18.     public void add(Object o){
  19.         Node node = new Node(o,null);
  20.         if(head == null){ //如果头结点为空
  21.             head = node;
  22.             tail = node;
  23.             node.setNext(null);
  24.         }else{
  25.             tail.setNext(node);
  26.             tail = node;
  27.         }
  28.         size++;
  29.     }
  30.     
  31.     /**
  32.      * 获取长度
  33.      * @return
  34.      */
  35.     public int size(){
  36.         return size;
  37.     }
  38.     public Iterator iterator(){
  39.         return new LinkedListIterator();
  40.     }
  41.     
  42.     /**
  43.      * 迭代器的内部类实现
  44.      */
  45.     private class LinkedListIterator implements Iterator{

  46.         private Node currentNode = head;
  47.         
  48.         @Override
  49.         public boolean hasNext() {
  50.             // TODO Auto-generated method stub
  51.             if(currentNode== null){
  52.                 return false;
  53.             }
  54.             else return true;
  55.         }


  56.         @Override
  57.         public Object next() {
  58.             Node node = currentNode;
  59.             currentNode = currentNode.getNext();
  60.             return node;
  61.         }
  62.     }
  63. }
4、第四个文件:TestMain.java

点击(此处)折叠或打开

  1. /**
  2.  * 测试Main方法
  3.  */
  4. public class TestMain {

  5.     public static void main(String [] args){
  6.         Collection c = new MyLinkedList();
  7.         for(int i=0;i<5;i++){
  8.             Object o = new Object();
  9.             System.out.println("序号:" + i + " 对象:" + o);
  10.             c.add(o);
  11.         }
  12.         
  13.         Iterator it = c.iterator();
  14.         while(it.hasNext()){
  15.             Node o = (Node) it.next();
  16.             System.out.println(o.getData());
  17.         }
  18.     }
  19. }
好了,以上就是我们对迭代器模式的应用实现,下面总结下迭代器模式的优点:
(1)、封装容器的内部实现细节,简化客户端的访问和获取容器内数据。
(2)、客户端可以通过相同的方式遍历不同的容器对象。
(3)、我们可以根据客户端需求让容器实现不同的迭代算法,从而可以用不同的遍历方式来访问容器数据。

阅读(5738) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~