线性表中迭代器的内部实现(Iterator、ListIterator)
来源:互联网 发布:linux root修改密码 编辑:程序博客网 时间:2024/05/12 06:48
独立的迭代器与内部的迭代器
独立类迭代器必须通过ADT的公用方法来访问ADT的数据,如果某些ADT,如堆,没有提供足够的数据访问方法,使得不能实现这种迭代器。另外,独立类迭代器比其他类型的迭代器的运行时间要长。但是,独立类的迭代器的实现往往比较简单。内部类迭代器可以直接访问ADT的数据,因此它往往比单个类的迭代器运行速度快。其实现单价也更大。迭代器的方法为什么要在自己的类中?因为如果迭代器的方法在ADT中,某个时候只能有一个遍历,而且,需要使用一些不属于接口Iterator的操作来初始化遍历。
Iterator接口
Java类库在java.util包中提供了该接口。Iterator接口只描述了3个方法:hasNext、next和remove。这些方法从第一个数据元素开始遍历数据集。
hasNext():测定迭代器是否完成遍历并越过数据集中的最后一个元素,若是,则返回false,否则返回true.
next():提取集合集中当前(下一个)元素并迭代前进一个位置
remove():从数据集中删除next()返回的最后一个元素,此后调用next()的行为将与删除前一样
下面是iterator在以数组方式实现的线性表中的内部实现,在以链表实现的线性表类似。就是用nextNode=nextNode.next代替nextIndex++,判断hasNext(),就是判断nextNode是否为空。
/** * 在数组方式实现的线性表中,作为内部类实现其迭代器,java类库arrayList中已实现其迭代器Iterator * @key * @author S.M.Q * 2014年9月14日下午8:04:58 */private class IteratorForArrayList implements Iterator<T>{private int nextIndex;private boolean isCalledNext;IteratorForArrayList(){nextIndex=0;isCalledNext=false;}/** * 判断是否到该线性表的最后一个元素,只要判断下一个元素的索引是否小于该线性表的长度 */public boolean hasNext(){return nextIndex<length;}/** * 返回下一个元素,并将索引往前进一步 * 为防止数组越界,判断一下当前索引是否小于线性表的长度,否则抛出异常 */public T next(){if(nextIndex<length){isCalledNext=true;return entry[nextIndex++];}elsethrow new NoSuchElementException("no illegal exception");}/** * 删除的当前元素,故该方法只能在调用next之后调用,此处用isCalledNext标识next是否调用 * 其他调用则派出非法异常 */public void remove(){if(isCalledNext){ MyArrayList.this.remove(nextIndex); nextIndex--; isCalledNext=false;}elsethrow new IllegalStateException(" illegal state exception");}}ListIterator接口
该接口是Java类库中提供的另一个迭代器接口,这种迭代器允许双向遍历线性表,并且在遍历过程中可以修改线性表。除了Iterator接口说明的3个方法hasNext、next和remove之外,ListIterator还含有诸如hasPrevious、previous、add和set方法
hasPrevious:检查迭代是否已完成遍历并到达数据集中的第一个元素之前
previous:提取线性表中前一个元素并将迭代向前移动一个
add:向线性表中插入元素,插入位置在next()可能返回的元素之前,previous可能返回的元素之后,插入之后,调用previous()将返回新元素,而调用next()将与插入前的一样
set:替换线性表中由next()或previous()刚返回的最后一个元素
下面是以数组方式实现的线性表,ListIterator作为内部类的实现,链表方式与数组方式类似:
/** * 数组方式实现的线性表中,作为内部类实现其迭代,java在arrayList中已经实现listIterator * @key * @author S.M.Q * 2014年9月14日下午9:02:28 */private class ListIteratorForArrayList implements ListIterator{private int nextIndex;private Move lastMove;private boolean isMoveOrSetLegal;/** * 该迭代器可以向前向后,所以只能用一个索引,通过增减索引实现其向前或者向后 * 向前或向后操作略有不同,故用一个枚举来记录其动作 * set或remove都是对当前元素进行操作,所以要设置一个标示,看是否能进行set或remove操作 */ListIteratorForArrayList(){nextIndex=0;isMoveOrSetLegal=false;lastMove=null;}/** * 与Iterator的hasNext类似 */public boolean hasNext(){return nextIndex<length;}/** * 与Iterator的next类似 */public T next(){if(hasNext()){isMoveOrSetLegal=true;lastMove=Move.NEXT;return entry[nextIndex++];}elsethrow new NoSuchElementException("no such element exception!");}/** * 查看当前索引是否大于0,如果大于0,说明当前元素不是位于线性表的第一个 */public boolean hasPrevious(){return nextIndex>0;}/** * 返回当前元素的前一个元素,并将迭代向前推进一个 * 记录相关特征,lastMove和nextIndex */public T previous(){if(hasPrevious()){isMoveOrSetLegal=true;lastMove=Move.PREVIOUS;nextIndex--;return entry[nextIndex];}elsethrow new NoSuchElementException("no such element exception!");}/** * 移除当前元素,remove操作需要在调用next()和previous之后。才能进行操作,故根据isMoveOrSetLegal的状态来 * 进行是否可以进行remove操作,我实现的MyArrayList实现的remove函数的参数,是该元素的位置,而调用过next之后,当前索引加1, * 调用previous之后,当前索引需要加1,才是位置(因为nextIndex是从0开始的) * 最后由于移除掉一个元素,当前的索引需要自减1,因为线性表的长度减一了 */public void remove(){if(isMoveOrSetLegal){isMoveOrSetLegal=false;if(lastMove==Move.NEXT)MyArrayList.this.remove(nextIndex);else{ nextIndex++; MyArrayList.this.remove(nextIndex);}nextIndex--;}elsethrow new IllegalStateException("illegal operation!");}/** * 返回下一个索引 */public int nextIndex(){int result;if(hasNext())result=nextIndex;elseresult=length;return result;}/** * 返回前一个索引 */public int previousIndex(){int result;if(hasPrevious())result=nextIndex-1;elseresult=-1;return result;} /** * 根据标识,看是否能操作set,否则抛出异常 * 调用线性表内部的set方法 */@Overridepublic void set(Object e) {// TODO Auto-generated method stubif(isMoveOrSetLegal){if(lastMove==Move.NEXT)MyArrayList.this.replace(nextIndex,(T)e);elseMyArrayList.this.replace(nextIndex+1,(T)e);}elsethrow new IllegalStateException("illeagl operation");} /** * 同样也是调用线性表内部的add方法 * 然后索引需要自增1,因为线性表的长度增1了 */@Overridepublic void add(Object e) {isMoveOrSetLegal=true;nextIndex++;MyArrayList.this.add(nextIndex,(T)e);}}
- 线性表中迭代器的内部实现(Iterator、ListIterator)
- Iterator和listIterator的区别
- Iterator和ListIterator的用法
- Iterator跟ListIterator的区别
- Iterator 与ListIterator的区别
- Iterator和listIterator的区别
- Iterator和listIterator的区别
- Iterator和ListIterator的区别
- Iterator和ListIterator的区别
- Iterator和ListIterator的知识点
- Iterator和ListIterator的区别
- Iterator和ListIterator的区别
- Iterator和ListIterator的区别
- Iterator和ListIterator的区别
- ListIterator &Iterator
- Iterator & ListIterator
- Iterator ListIterator
- Iterator和ListIterator的不同使用方法
- CGlib
- ARM开发版uboot烧写
- 撒开了的喀纳斯的天文台
- 求职
- JavaScript delete解析
- 线性表中迭代器的内部实现(Iterator、ListIterator)
- JS基础闯关大作战
- getc与fgetc的区别
- Java中基本数据类型对象包装类(传智播客毕老师视频讲解)
- acm_icpc网络赛第三站:西安赛区
- 【关于实验】批量打开文件(用于自动读写数据)
- 20140914 【 动态规划 】 51nod 1183 . 编辑距离
- smali文件语法参考
- HDU 4989 Summary BestCoder Round #8 解题报告