java学习之迭代器浅谈
2016-03-30 23:05
483 查看
1、 为什么用迭代器?在进行集合的遍历时,我们需要根据不同的集合来写不同的for循环.。Iterator模式是用于遍历集合类的标准访问方法。它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内部结构。这也减少重复代码的产生。
2、 怎么实现迭代器?首先Collection接口继承了Iterable接口。在Iterable接口中只是定义了一个方法iterator()返回一个在一组 T 类型的元素上进行迭代的迭代器。 实现了Collection接口的类较多,这里就不在一一列举,还有一部分继续继承Collection接口的子接口。实现类一般分为两类:实现了该接口的抽象类(AbstractList<E>,AbstractSet<E>,AbstractMap<E>)和类。对于实现了该接口的抽象类,利用内部类实现iterator()方法。对于子接口而言,依然没有实现父类接口的方法(他也不能实现)。对于ArrayList和LinkedList而言,其继承了抽象的List类,实现了List接口还有其他的接口。由于继承了抽象的List类,所以可以采用iterator()方法,返回一个迭代器对象。
3、 在抽象类中的具体实现:
private class Itr implementsIterator<E> {
int cursor = 0;//”游标”,是子查询返回的本次操作的开始地址
/**
* Index of element returned by mostrecent call to next or
* previous. Reset to -1 if this element is deleted by acall
* to remove.
*/
int lastRet = -1;//最近返回的下一个或者前一个的元素索引,如果这个元素被回调函数移除。
/**
*list的状态标记modCount赋值给迭代器的状态标记。这里要约束的是只有一个迭代器对象在对其操作。
*/
int expectedModCount = modCount;
public boolean hasNext() {
//如果到list的最后一个元素,返回false。
return cursor != size();
}
//随着每次迭代,工作下标每次后移一位,最后一个元素取完,工作指针的大小和size()的返回值相等,所以hasNext()返回false,不再进行下一步的迭代。
public E next() {
checkForComodification();//每调用一次next()函数都会调用checkForComodification方法判断
try {
int i = cursor;//将工作下标付给I;
E next = get(i);//取第i个元素
lastRet = i;
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsExceptione) {
checkForComodification();
throw newNoSuchElementException();
}
}
public void remove() {
if (lastRet < 0)//无元素时无法移除元素。
throw newIllegalStateException();
checkForComodification();//检测是否满足删除条件
try {
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsExceptione) {
throw newConcurrentModificationException();
}
}
//此方法用来判断创建迭代对象的时候List的modCount与现在List的modCount是否一样,不一样的话就报ConcurrentModificationException异常
final void checkForComodification() {
if (modCount != expectedModCount)
throw newConcurrentModificationException();
}
}
List对象有一个成员变量modCount,它代表该List对象被修改的次数,每对List对象修改一次,modCount都会加1。Itr类里有一个成员变量expectedModCount,它的值为创建Itr对象的时候List的modCount值。用此变量来检验在迭代过程中List对象是否被修改了,如果被修改了则抛出java.util.ConcurrentModificationException异常。在每次调用Itr对象的next()方法的时候都会调用checkForComodification()方法进行一次检验,checkForComodification()方法中做的工作就是比较expectedModCount 和modCount的值是否相等,如果不相等,就认为还有其他对象正在对当前的List进行操作,那个就会抛出ConcurrentModificationException异常。
2、 怎么实现迭代器?首先Collection接口继承了Iterable接口。在Iterable接口中只是定义了一个方法iterator()返回一个在一组 T 类型的元素上进行迭代的迭代器。 实现了Collection接口的类较多,这里就不在一一列举,还有一部分继续继承Collection接口的子接口。实现类一般分为两类:实现了该接口的抽象类(AbstractList<E>,AbstractSet<E>,AbstractMap<E>)和类。对于实现了该接口的抽象类,利用内部类实现iterator()方法。对于子接口而言,依然没有实现父类接口的方法(他也不能实现)。对于ArrayList和LinkedList而言,其继承了抽象的List类,实现了List接口还有其他的接口。由于继承了抽象的List类,所以可以采用iterator()方法,返回一个迭代器对象。
3、 在抽象类中的具体实现:
private class Itr implementsIterator<E> {
int cursor = 0;//”游标”,是子查询返回的本次操作的开始地址
/**
* Index of element returned by mostrecent call to next or
* previous. Reset to -1 if this element is deleted by acall
* to remove.
*/
int lastRet = -1;//最近返回的下一个或者前一个的元素索引,如果这个元素被回调函数移除。
/**
*list的状态标记modCount赋值给迭代器的状态标记。这里要约束的是只有一个迭代器对象在对其操作。
*/
int expectedModCount = modCount;
public boolean hasNext() {
//如果到list的最后一个元素,返回false。
return cursor != size();
}
//随着每次迭代,工作下标每次后移一位,最后一个元素取完,工作指针的大小和size()的返回值相等,所以hasNext()返回false,不再进行下一步的迭代。
public E next() {
checkForComodification();//每调用一次next()函数都会调用checkForComodification方法判断
try {
int i = cursor;//将工作下标付给I;
E next = get(i);//取第i个元素
lastRet = i;
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsExceptione) {
checkForComodification();
throw newNoSuchElementException();
}
}
public void remove() {
if (lastRet < 0)//无元素时无法移除元素。
throw newIllegalStateException();
checkForComodification();//检测是否满足删除条件
try {
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsExceptione) {
throw newConcurrentModificationException();
}
}
//此方法用来判断创建迭代对象的时候List的modCount与现在List的modCount是否一样,不一样的话就报ConcurrentModificationException异常
final void checkForComodification() {
if (modCount != expectedModCount)
throw newConcurrentModificationException();
}
}
List对象有一个成员变量modCount,它代表该List对象被修改的次数,每对List对象修改一次,modCount都会加1。Itr类里有一个成员变量expectedModCount,它的值为创建Itr对象的时候List的modCount值。用此变量来检验在迭代过程中List对象是否被修改了,如果被修改了则抛出java.util.ConcurrentModificationException异常。在每次调用Itr对象的next()方法的时候都会调用checkForComodification()方法进行一次检验,checkForComodification()方法中做的工作就是比较expectedModCount 和modCount的值是否相等,如果不相等,就认为还有其他对象正在对当前的List进行操作,那个就会抛出ConcurrentModificationException异常。
相关文章推荐
- Struts1与Struts2原理 区别 详解 汇总
- 学习javaEE每一天2016.3.30
- JavaMail发送邮件
- java获取当前时间的年周月季度等的开始结束时间
- java读取配置中文乱码
- 在Struts2中使用ValueStack、ActionContext、ServletContext、request、session等
- java通过JDBC链接SQLServer2012
- #java读书笔记#多线程3
- JAVA中的继承
- RESTful Web Services之Struts2 REST
- Spring启动容器初始化Listener
- openssl和java关于rsa的交互
- JAVA数组排序
- JAVAEE 框架 2016-3-30
- 安卓开发之Kotlin和java双实现仿qq空间下拉图片拉伸
- 自学java之hibernate安装及配置
- Java Map集合 转化为List 并为List排序
- Struts2与Struts1的区别
- #java读书笔记#多线程2
- Struts2在eclipse运行的必须包