java迭代器 异常_java迭代器失效 | 学步园
今天在测试代码的时候出现一个异常ConcurrentModificationException,该异常网上很多解决方案以及解释,但我还是再记录一遍吧。
代码抽象出来是这样的:
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List list=new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
for (Integer i : list) {//这是迭代
if(i==3){
list.remove(new Integer(i));//引起异常的操作
}
}
}
}
该代码在运行期间就出现java.util.ConcurrentModificationException异常。
这个循环其实是对list进行迭代。
1.在迭代的时候怎么判断是否还有下一个(hasNext()方法怎么实现):
public boolean hasNext() {
return cursor != size();
}
cursor:Index of element to be returned by subsequent call to next
size():是该list的size
所以只要两者不相等,就认为还有元素。
2.迭代的时候怎么取下一个(next()方法怎么实现):
public E next() {
checkForComodification();
try {
E next = get(cursor);
lastRet = cursor++;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
modelCount:The number of times this list has been structurally modified.Structural modifications are those that change the size of the list, or otherwise perturb it in such a fashion that iterations in progress may yield incorrect results.
expectedModCount:期望的modelCount
这2个变量是有迭代器自己来维护的。
上面这段程序出现异常是因为我们使用Collection里面的remove方法进行删除,ArrayList的remove方法实现:
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
private void fastRemove(int index) {
modCount++; //***
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc do its work
}
modCount+1,导致modCount和expectedModCount不相等。
3.解决方法就是用迭代器自己的remove方法:
public void remove() {
if (lastRet == -1)
throw new IllegalStateException();
checkForComodification();
try {
AbstractList.this.remove(lastRet); //将modCount+1,实现如下
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount; //维护
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
public E remove(int index) {
RangeCheck(index);
modCount++; //***
E oldValue = (E) elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc do its work
return oldValue;
}
java迭代器 异常_java迭代器失效 | 学步园相关推荐
- java个人所得税计算_java个人所得税计算器 | 学步园
class Caculate{ private String name; private double money; private double actual; /** * @param usern ...
- Java点名分类_java实现点名 | 学步园
java实现点名,在文本中每行存一个名字. import java.io.File; import java.io.FileInputStream; import java.util.ArrayLis ...
- java利己线程_java利己线程 | 学步园
所谓利己线程,就是在运行时不考虑其它线程的运行权限和时间分配,一心只顾自己运行完成了事的这种线程,比如:while(true){............} 但是,如果{..........}的代码中要 ...
- java迭代例子_Java 迭代器的代码实例详解
一.摘要 迭代器模式是与集合共生共死的.一般来说,我们只要实现一个容器,就需要同时提供这个容器的迭代器.使用迭代器的好处是:封装容器的内部实现细节,对于不同的集合,可以提供统一的遍历方式,简化客户端的 ...
- java 编写异常_Java基础编程之异常处理
Java异常类是对于程序中可能出现的错误或者异常的一种处理方式.在设计程序的过程中,对于可能出现的异常错误,比如说用户输入错误,设备错误,磁盘满了或者代码错误等等,通常采用异常处理的方式来进行处理可能 ...
- java runtime 异常_Java中RuntimeException和Exception
在java的异常类体系中,Error和RuntimeException是非检查型异常,其他的都是检查型异常. 所有方法都可以在不声明throws的情况下抛出RuntimeException及其子类 不 ...
- java 多层异常_Java多层嵌套异常处理的基本流程
异常是程序中的一些错误,但并不是所有的错误都是异常,错误有时候是可以避免的.异常的对象有两个来源,一是Java运行时环境自动抛出系统生成的异常,而不管你是否愿意捕获和处理,它总要被抛出!比如除数为0的 ...
- linux java url 异常_java异常处理总结
找到一个关于异常总结的很详细的文章,分享下.异常在我们编程中很重,在适当的位置,合理的处理或者抛出异常,对程序来说至关重要. 转:异常处理是程序设计中一个非常重要的方面,也是程序设计的一大难点,从C开 ...
- java runnable 异常_Java实现多线程异常捕获Runnable的案例
这篇文章主要介绍了详解Java中多线程异常捕获Runnable的实现的相关资料,希望通过本文能帮助到大家,让大家理解掌握这样的知识,需要的朋友可以参考下 详解Java中多线程异常捕获Runnable的 ...
最新文章
- 四说大数据时代“神话”:从大数据到深数据\n
- maven pom配置文件样本
- OpenGL mipmap filters贴图过滤的实例
- Error:Can’t find import 2508 in coredll.dll问题解决
- php hmacsha1计算,PHP HMAC_SHA1 算法 生成算法签名
- 第四讲 数学公理化方法(上)
- 苹果macfcpx视频剪辑软件:Final Cut Pro X
- 怎么调用获取被创建的预制体_PostgreSQL为每一个backend创建的cache
- python基础四 面向对象编程
- 2015 年五大移动端设计趋势
- 华为 21 级程序员月薪曝光:270k 封神!众网友直呼长见识
- 迅为i.MX6ULL终结者Mfgtools修改单独只烧写Uboot,内核,文件系统
- 《kafka面试100例 -6》如果在/admin/delete_topics/中手动写入一个节点会不会正常删除Topic
- docker下mysql主从搭建
- 0918 iOS10兼容/iOS系统过高或过低配置包/混合引擎的在线视频连麦互动直播/源码管理工具/Xcode8插件升级/导航栏渐变
- Hadoop实战问题记录
- 2013年中国android智能手机用户调查研究报告,ZDC:2013年7月中国智能手机市场分析报告...
- 数据异质性会影响深度学习变化检测模型的迁移能力,请列出提升模型迁移性的解决思路...
- 运算放大器偏置电阻的计算
- PR剪辑教学之电影混剪案例
热门文章
- Java项目打war包的方法
- Matlab如何求离散点的导数
- error c4996: 'fopen' This function or variable may be unsafe如何解决
- UBUNTU下双显示器设置
- 计算机在智慧交通的应用论文,智能交通的毕业论文
- 华为堡垒机_运维堡垒机----Gateone
- uniapp无法使用substr_关公战秦琼------Excel、SPSS Modler和R的使用对比(下)
- 一句话木马绕过linux安全模式,一句话木马(webshell)是如何执行命令的
- java 获取oracle mysql sqlserver 链接 connection
- php-cli下载,php-cli-color