您的位置:首页 > 编程语言 > Java开发

java设计模式_iterator

2015-04-27 20:48 369 查看
最近在看设计模式,将所学的简单整理出来,菜鸟所写,大神勿喷!

在java se中,Iterator是个接口,主要其中存在三个方法:hasNext(),next()和move()方法。所有的实现了iteratable超级接口的类都需实现iterator接口(abstract你懂的),而我们日常使用iterator最多的,就在在Collection集合中便利元素。因此主要说明在Collection中Iterator的实现和使用.

第一步,我们使用最原始的的数组模拟我们常见的ArrayList,取名MyArrayList,在动态改变内部数组长度时,参考了sun对ArrayList内部数组动态增长的方法,上代码:

<span style="font-size:18px;">/**
 * 使用数组模拟arrayList生成
 * @author Administrator
 */
public class MyArrayList {
	private Object[] objects = new Object[10];
	private int index  = 0 ;
	
	public void add(Object obj){
		
		if(index == objects.length){
			Object[] newObj = new Object[objects.length + (objects.length >> 1)] ;
			System.arraycopy(objects, 0, newObj, 0, objects.length);
			objects = newObj ;
		}
		objects[index++] = obj ;
	}
	
	public int size() {
		return index ;
	}
}</span>
由于是简单模拟,故只是简单实现了arrayList中的add()和size()方法,实现内容比较简单,因此不多说。在Collection,还存在另外一种List,叫LinkedList,是由链表生成的,现在我们也是用链表简单模拟一下该类是实现。
<span style="font-size:18px;">/**
 * 使用链表模拟LinkedList
 * @author Administrator
 */
public class MyLinkedList{
	//链表头部
	private Node head ;
	//链表末尾
	private Node last ;
	//记录LinkedList的大小
	private int index ;
	
	public void add(Object obj){
		Node node = new Node(obj , null);
		Node oldLast = last ;
		last = node ;
		if(oldLast == null){
			head = node ;
		}else{
			oldLast.setNext(node); 
		}
		index ++ ;
	}

	public int size() {
		return index ;
	}
	
	class Node{
		//数据列
		private Object obj ;
		//指向下一个
		private Node next ;
		
		public Node(Object obj, Node next) {
			super();
			this.obj = obj;
			this.next = next;
		}
		public Node() {
			super();
		}
		public Object getObj() {
			return obj;
		}
		public void setObj(Object obj) {
			this.obj = obj;
		}
		public Node getNext() {
			return next;
		}
		public void setNext(Node next) {
			this.next = next;
		}
	}
}</span>
同时,它也实现了add()和size()方法。为了能随时快速变换MyArrayList和MyLinkedList,我们使两类都继承一个抽象类,取名MyCollection,其中存在两个方法,add()和size(),代码如下:
<span style="font-size:18px;">public abstract class MyCollection {

	abstract void add(Object obj) ;
	
	abstract int size() ;

}</span>
那么,MyArrayList和MyLinkedList代码应该更改为:
<span style="font-size:18px;">public class MyLinkedList extends MyCollection
public class MyArrayList extends MyCollection</span>

此时,只要持有MyCollection的引用,都可以指向MyLinkedList或者MyArrayList,多态的概念就应运而生。但是,一旦我们使二者去继承MyCollection,我们就不得不面临这样一个问题,如何去遍历我们集合中的元素?MyArrayList是由数组构成的,当然你可以for遍历其中所有元素;MyLinkedList是由链表组成的,此时你肯定不能使用for循环去遍历,而应该而查询链表。因此,我们不得不面临这种问题:对于不同的MyCollection子类,我们都必须实现其不同的遍历方法,这显然不是我们所愿意的,因此在此引出了Iterator接口,使用该接口来为MyCollection遍历元素,对于自己的子类,需要返回一个Iterator,来实现自己内部的遍历方法.

<span style="font-size:18px;">public interface MyIterator {

	boolean hasNext() ;
	
	Object next() ;
}</span>
在MyCollection中,加个抽象方法,返回我们需要的一个指向MyIterator方法:
<span style="font-size:18px;">public abstract class MyCollection {

	abstract void add(Object obj) ;
	
	abstract int size() ;

	abstract MyIterator iterator() ;
}
</span>
如此同时,我们同时需要在MyArrayList和MyLinkedList中实现我们的MyIterator()方法,对于MyArrayList方法:
<span style="font-size:18px;">/**
 * 使用数组模拟arrayList生成
 * @author Administrator
 */
public class MyArrayList extends MyCollection{
	private Object[] objects = new Object[10];
	private int index  = 0 ;
	
	public void add(Object obj){
		
		if(index == objects.length){
			Object[] newObj = new Object[objects.length + (objects.length >> 1)] ;
			System.arraycopy(objects, 0, newObj, 0, objects.length);
			objects = newObj ;
		}
		objects[index++] = obj ;
	}
	
	public int size() {
		return index ;
	}

	@Override
	MyIterator iterator() {
		return new InnerIterator();
	}
	
	class InnerIterator implements MyIterator{

		private int currentIndex  = 0 ;
		
		public boolean hasNext() {
			return currentIndex < index;
		}

		public Object next() {
			return objects[currentIndex++];
		}
		
	}
	
}</span>
对于我们的MyLinkedList:
<span style="font-size:18px;">/**
 * 使用链表模拟LinkedList
 * @author Administrator
 */
public class MyLinkedList extends MyCollection{
	//链表头部
	private Node head ;
	//链表末尾
	private Node last ;
	//记录LinkedList的大小
	private int index ;
	
	public void add(Object obj){
		Node node = new Node(obj , null);
		Node oldLast = last ;
		last = node ;
		if(oldLast == null){
			head = node ;
		}else{
			oldLast.setNext(node); 
		}
		index ++ ;
	}

	public int size() {
		return index ;
	}
	
	class Node{
		//数据列
		private Object obj ;
		//指向下一个
		private Node next ;
		
		public Node(Object obj, Node next) {
			super();
			this.obj = obj;
			this.next = next;
		}
		public Node() {
			super();
		}
		public Object getObj() {
			return obj;
		}
		public void setObj(Object obj) {
			this.obj = obj;
		}
		public Node getNext() {
			return next;
		}
		public void setNext(Node next) {
			this.next = next;
		}
	}

	@Override
	public MyIterator iterator() {
		return new InnerIterator();
	}
	
	class InnerIterator implements MyIterator{

		private int currentIndex = 0 ;
		private Node currentNode =head ;
		
		public boolean hasNext() {
			return currentIndex < index ;
		}

		public Object next() {
			currentIndex ++ ;
			Object  obj = currentNode.getObj() ;
			currentNode = currentNode.getNext() ;
			return obj ;
		}
		
	}
	
}</span>
由代码可以看出,我们在两种不同类中实现的Iterator方法完全不同,但是在遍历时,只需要知道遍历的方法,而无需知道内部实现的机制。因此,只要是继承了MyCollection抽象类的子类,其内部只要实现了Iterator遍历方法即可,那么在使用父类的引用时,无需考虑子类的格式,使用Iterator即可,例如:
<span style="font-size:18px;">public class TestCollection {

	public static void main(String[] args) {
		
//		MyCollection collection = new MyLinkedList() ;
		MyCollection collection = new MyArrayList() ;
		for (int i = 0; i < 20; i++) {
			collection.add(new Person(i,"tom"));
		}
		System.out.println(collection.size());
		
		MyIterator myIt = collection.iterator() ;
		while(myIt.hasNext()){
			System.out.println(myIt.next().toString());
		}
	}
}</span>
好了,Iterator模式就差不多了,使用该模式主要是解决多态中不同子类的实现,父类对于某个特性进行宏观的控制而产生的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: