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();
}
}
}
来源:CSDN
作者:ac小人物
链接:https://blog.csdn.net/a1647237123/article/details/78633185