面向对象编程思想中,多态是一个最重要的特性,代码灵活性的体现主要是靠这种思想来实现的。现在模拟Sun公司当中的两个集合类LinkedList和ArrayList。这些具体的容器,都可以用一个Collection的接口来接收。最常用的就是遍历容器,而现在不同的容器,遍历它们的具体实现是不同的,而我们可以将遍历的方法封装到一个接口Iterator当中,在这个接口当中实现hasNext()和next()的方法,再由具体的容器去实现它。而作为用户,只需要知道这个容器当中的两个方法就行了,具体的遍历实现,由不同的容器自身给出。
1 package programe.iterator.model; 2 3 public interface Collection { 4 public void add(Object o); 5 public int size(); 6 public Iterator iterator(); 7 } 8 9 10 public interface Iterator {11 public Object next();12 public boolean hasNext();13 }
1、ArrayList容器的实现
1 package programe.iterator.model; 2 3 public class ArrayList implements Collection{ 4 Object[] objects=new Object[10]; 5 int index=0; 6 @Override 7 public void add(Object o) { 8 if(index==objects.length) { 9 Object[]newObjects=new Object[objects.length*2];10 System.arraycopy(objects,0,newObjects,0,objects.length);11 objects=newObjects;12 }13 objects[index]=o;14 index++;15 }16 17 @Override18 public Iterator iterator() {19 return new ArrayListIterator();20 }21 22 @Override23 public int size() {24 return index;25 }26 27 private class ArrayListIterator implements Iterator {28 private int currentIndex=0;29 @Override30 public boolean hasNext() {31 if(currentIndex>=index) {32 return false;33 }34 return true;35 }36 37 @Override38 public Object next() {39 Object o=objects[currentIndex];40 currentIndex++;41 return o;42 }43 44 }45 }
2、LinkedList容器实现
1 package programe.iterator.model; 2 3 public class Node { 4 5 private Object data; 6 private Node next; 7 public Node(Object data,Node next) { 8 this.data=data; 9 this.next=next;10 }11 public Object getData() {12 return data;13 }14 public void setData(Object data) {15 this.data = data;16 }17 public Node getNext() {18 return next;19 }20 public void setNext(Node next) {21 this.next = next;22 }23 24 }25 26 27 public class LinkedList implements Collection{28 29 Node head=null;30 Node tail=null;31 int size=0;32 @Override33 public void add(Object o) {34 Node n=new Node(o,null);35 if(head==null) {36 head=n;37 tail=n;38 size=1;39 return;40 }41 tail.setNext(n);42 tail=n;43 size++;44 }45 46 @Override47 public Iterator iterator() {48 return new LinkedListIterator();49 }50 51 @Override52 public int size() {53 return size;54 }55 56 private class LinkedListIterator implements Iterator {57 Node currentNode=head;58 @Override59 public boolean hasNext() {60 if(currentNode.getNext()==null) {61 return false;62 }63 return true;64 }65 66 @Override67 public Object next() {68 if(currentNode==head) {69 currentNode=currentNode.getNext();70 return head;71 }72 73 Node next=currentNode.getNext();74 currentNode=next;75 return next;76 }77 }78 }
测试代码:
1 public class Main { 2 public static void main(String[]args) { 3 //Collection c=new ArrayList(); 4 Collection c=new LinkedList(); 5 for(int i=0;i<15;i++) { 6 c.add(i); 7 } 8 System.out.println(c.size()); 9 10 Iterator iter=c.iterator();11 while(iter.hasNext()) {12 System.out.println(((Node)iter.next()).getData());13 }14 }15 }
评论:LinkedList容器是基于链表的;ArrayList容器是基于数组的。它们的构造不同,因此遍历方式也不同,如果不提供Iterator这样一个公共方法的接口给用户。那么用户需要记住每一种容器的遍历方法,而现在用户只需记住Iterator接口当中提供的方法即可。这里面的方法适合遍历实现了Iterator接口的容器。遍历只是一个容器具有的方法,不能说将所有的容器都去实现这个方法的接口,因此这里还提供了一个Collection接口,所有容器的接口,而Iterator这个接口仅仅只是Collection接口当中提供的一个方法。因为,各种具体容器除了遍历之外,肯定还有其他的公共需求,这时,一个Collection就可以将具体容器的实现暴露给用户,极大的方便了编程。