打赏

Java模拟容器的迭代器(Iterator模式)

   Iterator模式提供一系列的方法用于遍历某一类聚合对象的各个元素,在此,通过模拟容器的迭代器来学习Iterator模式。

         首先,模拟实现JAVA中用得最多的ArrayList和LinkedList,当然这2类容器都是实现Collection接口的,为什么要实现Collection接口?最根本的原因肯定是多态。

        

 1 /**
 2  * 
 3  * @author LingJian
 4  *
 5  */
 6 public class ArrayList implements Collection {
 7     private Object[] objects = new Object[10];
 8     private int index = 0;
 9     
10     public void add(Object o) {
11         if(index == objects.length) {
12             Object[] newObjects = new Object[objects.length * 2];
13             System.arraycopy(objects, 0, newObjects, 0, objects.length);
14             objects = newObjects;
15         }
16         objects[index] = o;
17         index ++;
18     };
19     
20     public int size() {
21         return index;
22     };
23 }
 1 public class LinkedList implements Collection {
 2     //
 3     private Node head = null;
 4     //
 5     private Node tail = null;
 6     private int index = 0;
 7     
 8     public void add(Object o) {
 9         Node n = new Node(o,null);
10         if(head == null) {
11             head = n;
12             tail = n;
13         }
14         tail.setNext(n);
15         tail = n;
16         index ++;
17     }
18     
19     public int size() {
20         return index;
21     }
22 }
 1 public class Node {
 2     private Object data;
 3     private Node next;
 4     public Object getData() {
 5         return data;
 6     }
 7     public void setData(Object data) {
 8         this.data = data;
 9     }
10     public Node getNext() {
11         return next;
12     }
13     public void setNext(Node next) {
14         this.next = next;
15     }
16     public Node(Object data, Node next) {
17         super();
18         this.data = data;
19         this.next = next;
20     }
21 }
1 /**
2  * 
3  * @author LingJian
4  *
5  */
6 public interface Collection {
7     public void add(Object o);
8     public int size();
9 }
 1 /**
 2  * 
 3  * @author LingJian
 4  *
 5  */
 6 public class Test {
 7 
 8     /**
 9      * @param args
10      */
11     public static void main(String[] args) {
12         Collection c = new LinkedList();
13         for(int i=0; i<15; i++) {
14             c.add(new Cat(i));
15         };
16         System.out.println(c.size());
17         
18                 
19     }
20 
21 }
 1 /**
 2  * 
 3  * @author LingJian
 4  *
 5  */
 6 public class Cat {
 7     private int id;
 8 
 9     public Cat(int id) {
10         super();
11         this.id = id;
12     }
13 
14     /**
15      * 方便打印查看
16      */
17     @Override
18     public String toString() {
19         // TODO Auto-generated method stub
20         return "cat:" + id;
21     }
22 }

   OK,如果不想用ArrayList,可以轻松切换LinkedList就能换一个容器,这就是多态给我们带来的好处。

         现在,容器能容纳东西,那如果要取出来呢?

        

 1 /**
 2  * 
 3  * @author LingJian
 4  *
 5  */
 6 public class Test {
 7 
 8     /**
 9      * @param args
10      */
11     public static void main(String[] args) {
12         Collection c = new ArrayList();
13         for(int i=0; i<15; i++) {
14             c.add(new Cat(i));
15         };
16         System.out.println(c.size());
17         
18         ArrayList al = (ArrayList) c;
19         for(int i=0; i<al.size();i++) {
20             .....
21         }
22                     }
23 }

     是的,这样写完全没有错,但是如果这时候发现容器换成了LinkedList,这段代码就需要全部替换了,因为LinkedList内部结构的实现是链表,遍历的方式不一样了,所以我们需要设计出一种可以不关注聚合对象内部元素结构的方法,不管是遍历什么容器,都能使用,无须更改方法。OK,Iterator模式就是为了解决这一一类问题而出现的,在这主要写LinkedList的Iterator。

        

1 /**
2  * 
3  * @author LingJian
4  *
5  */
6 public interface Iterator {
7     Object next();
8     boolean hasNext();
9 }
 1 /**
 2  * 
 3  * @author LingJian
 4  *
 5  */
 6 public class LinkedList implements Collection {
 7     //
 8     private Node head = null;
 9     //
10     private Node tail = null;
11     private int index = 0;
12     
13     public void add(Object o) {
14         Node n = new Node(o,null);
15         if(head == null) {
16             head = n;
17             tail = n;
18         }
19         tail.setNext(n);
20         tail = n;
21         index ++;
22     }
23     
24     public int size() {
25         return index;
26     }
27 
28     @Override
29     public Iterator iterator() {
30         return new LinkedListIterator();
31     }
32     
33     public class LinkedListIterator implements Iterator {
34         
35         @Override
36         public Object next() {
37             Object o = head.getData();
38             head = head.getNext();
39             return o;
40         }
41 
42         @Override
43         public boolean hasNext() {
44             if(head == null) return false;
45             else return true;
46         }
47         
48     }
49 }
 1 /**
 2  * 
 3  * @author LingJian
 4  *
 5  */
 6 public class Test {
 7 
 8     /**
 9      * @param args
10      */
11     public static void main(String[] args) {
12         Collection c = new LinkedList();
13         for(int i=0; i<15; i++) {
14             c.add(new Cat(i));
15         };
16         System.out.println(c.size());
17         
18         
19         
20         Iterator it = c.iterator();
21         while(it.hasNext()) {
22             Object o =     it.next();
23             System.out.print(o + " ");
24         }
25         
26     }
27 
28 }

         有了Iterator,遍历的聚合对象只要对外提供了自己符合要求的Iterator,这段遍历的方法便可重复使用,完全不需要关注元素的内部结构。

         Iterator模式主要用于遍历,所以相对来说比较简单。

posted @ 2013-04-08 23:51  lingjiango  阅读(1505)  评论(2编辑  收藏  举报