ListIterator中方法的源码实现,及一些异常问题剖析
2018-04-08 21:50
537 查看
个人博客地址:https://blog.csdn.net/qq_41907991
本文如有不懂可参考如下博客
集合源码解析:
https://blog.csdn.net/u011240877/article/details/52752589
JavaConcurrentModificationException异常原因和解决方法:
https://blog.csdn.net/androidboy365/article/details/50540202/
文章重点在于解析在迭代过程中出现的 java.lang.IllegalStateException。
问题代码如下:
以下为ListIterator中add();set();remove();,next();
private final class FullListIterator extends SimpleListIterator implements ListIterator<E> {
//根据 start 指定游标位置
FullListIterator(int start) {
if (start >= 0 && start <= size()) {
pos = start - 1;
} else {
throw new IndexOutOfBoundsException();
}
}
//在游标前面添加元素
public void add(E object) {
if (expectedModCount == modCount) {
try {
//调用子类的添加操作,ArrayList, LinkedList,Vector 的添加操作实现有所不同
AbstractList.this.add(pos + 1, object);
} catch (IndexOutOfBoundsException e) {
throw new NoSuchElementException();
}
//游标后移一位
pos++;
//!注意! 添加后 上次迭代位置又变回 -1 了,说明 add 后调用 remove, set 会有问题!
lastPosition = -1;
if (modCount != expectedModCount) {
expectedModCount = modCount;
}
} else {
throw new ConcurrentModificationException();
}
}
//当游标不在初始位置(-1)时返回true
public boolean hasPrevious() {
return pos >= 0;
}
//游标后面的元素索引,就是游标 +1
public int nextIndex() {
return pos + 1;
}
//游标前面一个元素
public E previous() {
if (expectedModCount == modCount) {
try {
E result = get(pos);
lastPosition = pos;
pos--;
return result;
} catch (IndexOutOfBoundsException e) {
throw new NoSuchElementException();
}
}
throw new ConcurrentModificationException();
}
//游标前面元素的索引,就是游标的位置,有点晕的看开头那几张图
public int previousIndex() {
return pos;
}
//更新之前迭代的元素为 object
public void set(E object) {
if (expectedModCount == modCount) {
try {
//调用子类的set
AbstractList.this.set(lastPosition, object);
} catch (IndexOutOfBoundsException e) {
throw new IllegalStateException();
}
} else {
throw new ConcurrentModificationException();
}
} 从源码中可以看出:
add方法跟remove方法在运行中,将lastpostion的位置重置到-1,并且remove方法自身在
运行时会进行lastpostion的判定,set方法修改元素的位置也是lastpostion,所以在add方法或
者remove方法后调用set方法会报错,连续调用两次remove方法也会报错,但是连续调用add方法不会报错,add的定位依赖
的是postion指针。
本文如有不懂可参考如下博客
集合源码解析:
https://blog.csdn.net/u011240877/article/details/52752589
JavaConcurrentModificationException异常原因和解决方法:
https://blog.csdn.net/androidboy365/article/details/50540202/
文章重点在于解析在迭代过程中出现的 java.lang.IllegalStateException。
问题代码如下:
以下为ListIterator中add();set();remove();,next();
private final class FullListIterator extends SimpleListIterator implements ListIterator<E> {
//根据 start 指定游标位置
FullListIterator(int start) {
if (start >= 0 && start <= size()) {
pos = start - 1;
} else {
throw new IndexOutOfBoundsException();
}
}
//在游标前面添加元素
public void add(E object) {
if (expectedModCount == modCount) {
try {
//调用子类的添加操作,ArrayList, LinkedList,Vector 的添加操作实现有所不同
AbstractList.this.add(pos + 1, object);
} catch (IndexOutOfBoundsException e) {
throw new NoSuchElementException();
}
//游标后移一位
pos++;
//!注意! 添加后 上次迭代位置又变回 -1 了,说明 add 后调用 remove, set 会有问题!
lastPosition = -1;
if (modCount != expectedModCount) {
expectedModCount = modCount;
}
} else {
throw new ConcurrentModificationException();
}
}
//当游标不在初始位置(-1)时返回true
public boolean hasPrevious() {
return pos >= 0;
}
//游标后面的元素索引,就是游标 +1
public int nextIndex() {
return pos + 1;
}
//游标前面一个元素
public E previous() {
if (expectedModCount == modCount) {
try {
E result = get(pos);
lastPosition = pos;
pos--;
return result;
} catch (IndexOutOfBoundsException e) {
throw new NoSuchElementException();
}
}
throw new ConcurrentModificationException();
}
//游标前面元素的索引,就是游标的位置,有点晕的看开头那几张图
public int previousIndex() {
return pos;
}
//更新之前迭代的元素为 object
public void set(E object) {
if (expectedModCount == modCount) {
try {
//调用子类的set
AbstractList.this.set(lastPosition, object);
} catch (IndexOutOfBoundsException e) {
throw new IllegalStateException();
}
} else {
throw new ConcurrentModificationException();
}
} 从源码中可以看出:
add方法跟remove方法在运行中,将lastpostion的位置重置到-1,并且remove方法自身在
运行时会进行lastpostion的判定,set方法修改元素的位置也是lastpostion,所以在add方法或
者remove方法后调用set方法会报错,连续调用两次remove方法也会报错,但是连续调用add方法不会报错,add的定位依赖
的是postion指针。
相关文章推荐
- 项目中遇到的一些问题或异常以及处理方法
- 使用OmniORB出现的一些问题及已实现的解决方法
- Mac中用Ant实现Android的批量打包碰到的一些问题以及解决方法
- TCMalloc的使用与源码剖析之九---------一些未解决的问题
- 通讯录结构体方法的实现 和VS中存在的一些问题的分析
- C++ Standard Stl -- SGI STL源码学习笔记(07) stl_vector 与 一些问题的细化 3 resize函数剖析
- Case:接口实现类的方法上使用AspectJ方式实现aop的异常问题
- C++ Standard Stl -- SGI STL源码学习笔记(06) stl_vector 与 一些问题的细化 2 push_back函数剖析
- 【最近面试遇到的一些问题】多线程有几种实现方法,都是什么?同步有几种实现方法,都是什么
- adaboost 算法在实现中的一些问题以及解决方法(持续更新)
- 设计实现OJ平台的遇到的一些问题和解决方法
- 通讯录结构体方法的实现 和VS中存在的一些问题的分析
- WinForms C#:html编辑器工程源码,含直接写WebBrowser的文件流、IPersistStreamInit接口的声明和一些相关的小方法
- >+ 后台文章管理的一些基本功能及实现方法
- 从vc6升级到vc7的一些问题及解决方法
- WinForms C#:html编辑器工程源码,含直接写WebBrowser的文件流、IPersistStreamInit接口的声明和一些相关的小方法
- 添加/删除程序空白窗口及控制面板窗口显示异常问题的解决方法
- 在VC中应用MSXML DOM 的一些基本实现方法
- 深入剖析Java编程中的中文问题及建议最优解决方法--上篇
- 数据挖掘中的DBSCAN聚类算法CSharp实现及一些问题