内部类迭代器

久未见 提交于 2019-12-02 12:00:53



package com.nobody.iterator;

/** 基础迭代器接口
 *
 *  迭代器用于遍历一个数据集,且在遍历过程中,可以查看、插入、删除、替换数据元素。 
 *  迭代器有3种类型:内部迭代器、外部迭代器和内部类迭代器
 *
 *  内部迭代器是将迭代器的操作添加到实现了ADT(线性表等)的类中得到的,因此它可以高效的访问ADT的数据,同一时刻该迭代器对同一个线性表只允许一个迭代。
 *
 *  外部迭代器是一个公有类的对象,该类实现了迭代器方法。这个类独立与实现了ADT的类,但与它相互作用。外部迭代器必须通过ADT的公有方法访问ADT的数据,
 *  因此,典型的外部迭代器会比其它种类的迭代器花更多的时间来执行操作,另外,外部迭代器允许多个迭代器各自独立遍历同一个ADT的数据。
 *  
 *  内部类迭代器是在实现了ADT的类的内部定义的内部类实例。迭代器方法实现在内部类内部,同内部迭代器一样,都可以直接访问ADT的数据,因此也同样高效,
 *  所付出的代价也一样,但是内部类迭代器和外部迭代器一样,都允许多个迭代器同时遍历访问同一个ADT的数据。
 *
 *  */
import java.util.NoSuchElementException;

public interface BasicIteratorInterface{
	/** Task: 设置迭代器初始位置于向数据集合第一个元素 */
	public void reset();

	/** Task: 判断迭代器的当前位置是否还在数据集内
	 *  @return 迭代器指向的位置不在数据集内则返回true,反之则返回false
	 */
	public boolean hasCurrent();

	/** Task:迭代器在当前位置上向后移一位
	 *  @return 若迭代器尚有可返回的另一个元素则返回true,否则返回false
	 */
	public boolean advance();
	
	/** Task: 若当前位置存在,返回迭代器当前位置的元素
	 *  @return Object 当前位置的对象
	 *  @throws NoSuchElementException 若当前位置存在
	 */
	public Object getCurrent() throws NoSuchElementException;
}


package com.nobody.iterator.childInterface;

import com.nobody.iterator.BasicIteratorInterface;
import java.util.NoSuchElementException;

/** 迭代器接口 */
public interface IteratorInterface extends BasicIteratorInterface{
	public void reset();
	public boolean hasCurrent();
	public boolean advance();
	public Object getCurrent() throws NoSuchElementException;
	
	/** task: 若当前位置存在,则在之前插入一个新元素
	 * @param newEntry 新元素对象
	 * @throws NoSuchElementException 当前元素不存在时
	 */
	public void addBeforeCurrent(Object newEntry) throws NoSuchElementException;

	/** Task: 若当前位置存在时,在之后插入一个新元素
	 *  @param newEntry 新元素对象
	 *  @throws NoSuchElementException 当前元素不存在时
	 */
	public void addAfterCurrent(Object newEntry) throws NoSuchElementException;

	/** Task: 若当前元素存在时,删除当前位置的元素
	 *  @throws NoSuchElementException 当前元素不存在时
	 */
	public void removeCurrent() throws NoSuchElementException;
	
	/** Task: 若当前位置存在时,替换一个新元素对象
	 *  @param newEntry 替换当前元素的对象
	 *  @throws NoSuchElementException 当前元素不存在时
	 */
	public void replaceCurrent(Object newEntry) throws NoSuchElementException;
}


package com.nobody.list;

/** ADT线性表接口
 *  线性表的元素位置从1开始
 */  
public interface ListInterface{

	/** Task:往线性表的末尾插入新元素
	 *  @param newEntry 做为新元素插入的对象
	 *  @return 如果插入成功则返回true,否则返回false
	 */
	public boolean add(Object newEntry);

	/** Task:往线性表的指定位置插入一个新元素,原本位于该位置及之后的元素各向后移动一个位置,线性表的大小增1.
	 *  @param newPosition 线性表新元素插入的位置,1 <= newPosition && getLength()+1 >= newPosition
	 *  @param newEntry 作为新元素插入的对象
	 *  @return 如果插入成功则返回true,否则返回false
	 */
	public boolean add(int newPosition, Object newEntry);

	/** Task:从线性表中删除指定位置的元素,原本位于该位置之后的元素各向前移动一个位置,线性表的大小减1
	 *  @param givenPosition 删除元素的指定位置,1 <= givenPosition && getLength() >= givenPosition 
	 *  @return 如果删除成功则返回被删除的元素,否则返回 null
	 */
	public Object remove(int givenPosition);

	/** Task: 从线性表中删除所有元素
	 */
	public void clear();
	
	/** Task: 从线性表中替换指定位置的元素
	 *  @param givenPosition 元素替换的指定位置,1 <= givenPosition && getLength() >= givenPosition
	 *  @param newEntry 用以替换givenPosition元素的对象
	 *  @return 如果替换成功则返回true,如果线性表为空或者givenPosition位置非法则返回false
	 */
	public boolean replace(int givenPosition, Object newEntry);

	/** Task: 从线性表的指定位置获取元素(对象的引用)
	 *  @param givenPosition 元素的索引位置,1 <= givenPosition && getLength() >= givenPosition
	 *  @return 如果索引成功则返回元素,否则返回null
	 */
	public Object getEntry(int givenPosition);

	/** Task: 判断线性表中是否含有给定的元素
	 *  @param anEntry 表示待查元素的对象
	 *  @return 如果线性表中存在anEntry则返回true,否则返回false 
	 */
	public boolean contains(Object anEntry);

	/** Task: 获取线性表的长度
	 *  @return 返回线性表当前所含元素的个数
	 */
	public int getLength();

	/** Task: 判断线性表是否为空
	 *  @return 如果为空则返回true,否则返回false
	 */
	public boolean isEmpty();

	/** Task: 判断线性表是否已满
	 *  @return 如果线性表已满则返回true,否则返回false
	 */
	public boolean isFull();

	/** Task: 按元素在线性表中的顺序,显示全部的元素
	 */
	public void display();
}


package com.nobody.list.childInterface;

import com.nobody.list.ListInterface;
import com.nobody.iterator.childInterface.IteratorInterface;

/** 获取一个线性表的迭代器接口 */
public interface ListWithIteratorInterface extends ListInterface{
	/** task: 返回一个迭代器
	 *  @return IteratorInterface 返回一个迭代器
	 */
	public IteratorInterface getListIterator();
}


package com.nobody.list.childInterface.linkedListWithIterator;

import com.nobody.list.childInterface.ListWithIteratorInterface;
import com.nobody.list.linkedsListNode.Node;
import com.nobody.iterator.childInterface.IteratorInterface;
import java.util.NoSuchElementException;

/** 使用链表实现ADT线性表,实现内部类迭代器 
 *  
 *  链表是由一个个节点的对象构成的,每一个节点都有两个部分,一部分含有基本类型的数据或者对数据对象的引用,另一部分引用链表中的下一个节点(即一部分
 *  存数据,另一部分存下一个节点的引用);但最后一个节点不引用下一个节点.表头引用和表尾引用位于链表之外,表头引用链表的第一个节点,表尾引用链表的
 *  最后一个节点。
 *  查询、插入、删除、替换链表中指定位置节点所存储的数据对象,都必须从表头开始按节点顺序遍历查找到指定节点,然后才能进行插入、删除、替换、获取等操
 *  作。
 *  删除、插入操作只需要知道两个节点(删除、插入位置与前一个位置的节点),就可以进行该操作,相对于使用数组实现线性表,链表不需要进行大量移位操作,
 *  但是每进行插入或删除操作,都需要从表头开始遍历节点寻找操作位置的节点引用。
 *  查询、替换操作相对于使用数组实现线性表,链表每查询或替换一个元素都需要从表头开始遍历查找,而数组可以直接获取指定位置的元素。
 *  
 *  链表解决了数组插入、删除大量移位的问题,但同时也带来了另一个问题,每次进行查询、替换等操作都需要从表头开始遍历索引节点,为了解决这一问题,在链
 *  表中引进了一个内部类迭代器,通过迭代器对象遍历线性表,在遍历的过程中迭代器记住在链表中所在位置节点的引用,并且可以进行插入、删除、替换、查询等
 *  操作,按我的理解迭代器就像一根指针,从线性表的表头开始指向每一个元素直到表尾结束,在此期间迭代器会记住当前元素的引用,并可以进行上述的增删等操
 *  作。
 * */ 

public class LinkedsListWithIterator implements ListWithIteratorInterface{ 
	private Node firstNode;			 //引用链表第一个节点
	private Node lastNode;			 //引用链表最后一个节点
	private int length;			 //链表长度
	
	public LinkedsListWithIterator(){
		clear();
	}

	public boolean add(Object newEntry){		//在线性表末尾插入对象
		Node newNode = new Node(newEntry);
		if(isEmpty()){				//线性表为空时
			this.firstNode = newNode;
		}else{					
			this.lastNode.setNext(newNode);
		}
		this.lastNode = newNode;
		this.length++;
		return true;
	}

	public boolean add(int newPosition, Object newEntry){	//在指定位置插入对象
		boolean result = false;
		if(newPosition >= 1 && newPosition <= this.length+1){
			Node newNode = new Node(newEntry);
			if(newPosition == 1){ 			//插入首部
				newNode.setNext(this.firstNode);
				this.firstNode = newNode;
				if(this.length == 0){
					this.lastNode = newNode;
				}
			} else if(newPosition == this.length+1){ //插入尾部
				this.lastNode.setNext(newNode);
				this.lastNode = newNode;
			} else{					//插入任意两节点之间
				Node nodeBefore = getNodeAt(newPosition-1);
				Node nodeAfter = nodeBefore.getNext();
				nodeBefore.setNext(newNode);
				newNode.setNext(nodeAfter);
			}
			this.length++;
			result = true;
		}
		return result;
	}

	public Object remove(int givenPosition){	//删除指定位置对象,并返回该对象
		Object result = null;
		if(givenPosition >= 1 && givenPosition <= this.length){
			if(givenPosition == this.length){	//删除末尾节点
				result = this.lastNode.getData();
				this.lastNode = getNodeAt(givenPosition-1);
				if(this.length == 1){		//如果链表只有一个节点
					this.firstNode = null;
				} else{
					this.lastNode.setNext(null);
				}
			} else if(givenPosition == 1){		//删除首部节点
				result = this.firstNode.getData();
				this.firstNode = this.firstNode.getNext();
			} else{					//删除任意两节点之间的节点
				Node nodeBefore = getNodeAt(givenPosition-1);
				Node nodeRemoveTo = nodeBefore.getNext();
				Node nodeAfter = nodeRemoveTo.getNext();
				nodeBefore.setNext(nodeAfter);
				result = nodeRemoveTo.getData();
			}
			this.length--;
		}
		return result;
	}

	public void clear(){				//清空线性表
		this.length = 0;
		this.firstNode = null;
		this.lastNode = null;
	}

	public boolean replace(int givenPosition, Object newEntry){	//替换指定位置对象
		boolean result = false;
		if(givenPosition >= 1 && givenPosition <= this.length){
			if(givenPosition == this.length){		//替换末尾节点存放的数据对象
				this.lastNode.setData(newEntry);
			} else{
				getNodeAt(givenPosition).setData(newEntry);
			}
			result = true;
		}
		return result;
	}

	public Object getEntry(int givenPosition){		//获取指定位置对象
		Object result = null;
		if(givenPosition >= 1 && givenPosition <= this.length){
			if(givenPosition == this.length){
				result = this.lastNode.getData();
			} else{
				result = getNodeAt(givenPosition).getData();
			}
		}
		return result;
	}

	public boolean contains(Object anEntry){		//判断线性表中是否存在anEntry
		boolean result = false;
		Node node = this.firstNode;
		while(!result && node != null){
			result = anEntry.equals(node.getData());
			node = node.getNext();
		}
		return result;
	}

	public int getLength(){			//获取当前线性表长度
		return this.length;
	}

	public boolean isEmpty(){		//判断线性表是否为空
		return this.length == 0;
	}

	public boolean isFull(){		//判断线性表是否已满
		return false;
	}

	public void display(){			//显示所有对象
		Node node = this.firstNode;
		for(int index = 1; index <= this.length; index++){
			System.out.println(node.getData());
			node = node.getNext();
		}
	}
	
	/** Task: 获取链表中指定位置的节点对象
	 *  @param givenPosition 指定位置
	 *  @return 返回指定位置的节点对象
	 */
	private Node getNodeAt(int givenPosition){
		Node result = null;
		if(givenPosition >= 1 && givenPosition <= this.length){ 	
			result = this.firstNode;
			for(int i = 1; i < givenPosition; i++){
				result = result.getNext();
			}
		}
		return result;
	}

	public IteratorInterface getListIterator(){	//创建一个线性表迭代器
		return new IteratorForLinkedsList();
	}

	private class IteratorForLinkedsList implements IteratorInterface{
		private Node currentNode;		//迭代器中的当前节点
		private Node beforeNode;		//当前节点之前的节点

		public IteratorForLinkedsList(){	
			this.currentNode = firstNode;
			this.beforeNode = null;
		}
		
		public void reset(){			//初始化迭代器,将迭代器初始位置于线性表的第一个元素
			this.currentNode = firstNode;
			this.beforeNode = null;
		}	

		public boolean hasCurrent(){		//判定迭代器位置是否在线性表内,还在则返回true,反之则返回false
			return this.currentNode != null;
		}

		public boolean advance(){		//若当前节点存在,则迭代器向后推进一位
			boolean result = false;
			if(hasCurrent()){
				this.beforeNode = this.currentNode;
				this.currentNode = this.currentNode.getNext();
				result = true;
			}
			return result;
		}

		public Object getCurrent() throws NoSuchElementException{	//若当前节点存在,则返回所存对象
			if(hasCurrent()){
				return this.currentNode.getData();
			} else{
				throw new NoSuchElementException("getCurrent(): 当前位置不存在元素");
			}
		}

		//若当前节点存在,则在当前节点之前插入一个元素
		public void addBeforeCurrent(Object newEntry) throws NoSuchElementException{
			if(hasCurrent()){
				Node newNode = new Node(newEntry);
				newNode.setNext(this.currentNode);
				if(this.beforeNode == null){		//判断当前节点是否线性表的第一个节点
					firstNode = newNode;
				} else{
					this.beforeNode.setNext(newNode);
				}
				this.beforeNode = newNode;
			} else{
				throw new NoSuchElementException("addBeforeCurrent(Object newEntry): 不存在元素");
			}
		}

		//若当前节点存在,则在当前节点之后插入一个元素
		public void addAfterCurrent(Object newEntry) throws NoSuchElementException{ 
			if(hasCurrent()){
				Node newNode = new Node(newEntry);
				if(this.currentNode.getNext() == null){		//判断当前节点是否线性表的最后一个节点
					lastNode = newNode;
				}
				newNode.setNext(this.currentNode.getNext());
				this.currentNode.setNext(newNode);
			} else{
				throw new NoSuchElementException("addAfterCurrent(Object newEntry): 当前位置不存在元素");
			}
		}
		
		public void removeCurrent() throws NoSuchElementException{  //若当前节点存在,则删除该节点
			if(hasCurrent()){
				if(this.beforeNode == null){		//判断当前节点是否是第一个节点
					firstNode = firstNode.getNext();
					this.currentNode = firstNode;
					if(firstNode == null){		//若线性表只有一个节点
						lastNode = null;
					}
				} else{
					this.beforeNode.setNext(this.currentNode.getNext());
					this.currentNode = this.currentNode.getNext();
					if(this.currentNode == null){	//若当前节点是最后一个节点
						lastNode = this.beforeNode;
					}
				}
			} else{
				throw new NoSuchElementException("removeCurrent(): 当前位置不存在元素");
			}
		}

		public void replaceCurrent(Object newEntry) throws NoSuchElementException{  //若当前节点存在,则替换新对象
			if(hasCurrent()){
				this.currentNode.setData(newEntry);
			} else{
				throw new NoSuchElementException("replaceCurrent(Object newEntry): 当前位置不存在元素");
			}
		}
	}

}


package com.nobody.list.linkedsListNode;

/** 链表中的节点类 */
public class Node{
	private Object data;	//数据部分
	private Node next;	//链接下一个节点

	public Node(Object data){
		this.data = data;
	}

	public Node(Object data, Node next){
		this.data = data;
		this.next = next;
	}

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

	public Object getData(){
		return this.data;
	}

	public void setNext(Node next){
		this.next = next;
	}

	public Node getNext(){
		return this.next;
	}
}



package com.nobody.test;

import com.nobody.list.ListInterface;
import com.nobody.list.childInterface.ListWithIteratorInterface;
import com.nobody.list.childInterface.linkedListWithIterator.LinkedsListWithIterator;
import com.nobody.iterator.childInterface.IteratorInterface;

/** 测试链表加内部类迭代器(LinkedsListWithIterator类) */
public class Client{
	public static void main(String[] args){
		ListWithIteratorInterface listIter = new LinkedsListWithIterator(); //创建一个由链表实现的线性表对象
		initializetion(listIter);					//初始化线性表
		displays(listIter);
		IteratorInterface iterator = listIter.getListIterator();	//创建一个迭代器对象
		testIterator(iterator);
	}

	private static void initializetion(ListInterface list){ 		//给线性表插入数据
		list.add("first");
		list.add("two");
		list.add("three");
		list.add("form");
		list.add("five");
	}

	private static void displays(ListInterface list){			//显示线性表中的数据
		list.display();
		System.out.println();
	}

	private static void testIterator(IteratorInterface iter){		//测试迭代器
		System.out.println("hasCurrent()   " + iter.hasCurrent());
		System.out.println("advance()   " + iter.advance());
		System.out.println("getCurrent()   " + iter.getCurrent());
		System.out.println("addAfterCurrent(six)");
		iter.addAfterCurrent("six");
		System.out.println("addBeforeCurrent(eight)");
		iter.addBeforeCurrent("eight");
		System.out.println("removeCurrent()");
		iter.removeCurrent();
		System.out.println("replaceCurrent(nine)");
		iter.replaceCurrent("nine");
		System.out.println("reset()");
		iter.reset();

		while(iter.hasCurrent()){	//遍历打印线性表
			System.out.println("getCurrent()   " + iter.getCurrent());
			iter.advance();
		}
	}
}


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!