今天在测试代码的时候出现一个异常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迭代器失效 | 学步园相关推荐

  1. java个人所得税计算_java个人所得税计算器 | 学步园

    class Caculate{ private String name; private double money; private double actual; /** * @param usern ...

  2. Java点名分类_java实现点名 | 学步园

    java实现点名,在文本中每行存一个名字. import java.io.File; import java.io.FileInputStream; import java.util.ArrayLis ...

  3. java利己线程_java利己线程 | 学步园

    所谓利己线程,就是在运行时不考虑其它线程的运行权限和时间分配,一心只顾自己运行完成了事的这种线程,比如:while(true){............} 但是,如果{..........}的代码中要 ...

  4. java迭代例子_Java 迭代器的代码实例详解

    一.摘要 迭代器模式是与集合共生共死的.一般来说,我们只要实现一个容器,就需要同时提供这个容器的迭代器.使用迭代器的好处是:封装容器的内部实现细节,对于不同的集合,可以提供统一的遍历方式,简化客户端的 ...

  5. java 编写异常_Java基础编程之异常处理

    Java异常类是对于程序中可能出现的错误或者异常的一种处理方式.在设计程序的过程中,对于可能出现的异常错误,比如说用户输入错误,设备错误,磁盘满了或者代码错误等等,通常采用异常处理的方式来进行处理可能 ...

  6. java runtime 异常_Java中RuntimeException和Exception

    在java的异常类体系中,Error和RuntimeException是非检查型异常,其他的都是检查型异常. 所有方法都可以在不声明throws的情况下抛出RuntimeException及其子类 不 ...

  7. java 多层异常_Java多层嵌套异常处理的基本流程

    异常是程序中的一些错误,但并不是所有的错误都是异常,错误有时候是可以避免的.异常的对象有两个来源,一是Java运行时环境自动抛出系统生成的异常,而不管你是否愿意捕获和处理,它总要被抛出!比如除数为0的 ...

  8. linux java url 异常_java异常处理总结

    找到一个关于异常总结的很详细的文章,分享下.异常在我们编程中很重,在适当的位置,合理的处理或者抛出异常,对程序来说至关重要. 转:异常处理是程序设计中一个非常重要的方面,也是程序设计的一大难点,从C开 ...

  9. java runnable 异常_Java实现多线程异常捕获Runnable的案例

    这篇文章主要介绍了详解Java中多线程异常捕获Runnable的实现的相关资料,希望通过本文能帮助到大家,让大家理解掌握这样的知识,需要的朋友可以参考下 详解Java中多线程异常捕获Runnable的 ...

最新文章

  1. 四说大数据时代“神话”:从大数据到深数据\n
  2. maven pom配置文件样本
  3. OpenGL mipmap filters贴图过滤的实例
  4. Error:Can’t find import 2508 in coredll.dll问题解决
  5. php hmacsha1计算,PHP HMAC_SHA1 算法 生成算法签名
  6. 第四讲 数学公理化方法(上)
  7. 苹果macfcpx视频剪辑软件:Final Cut Pro X
  8. 怎么调用获取被创建的预制体_PostgreSQL为每一个backend创建的cache
  9. python基础四 面向对象编程
  10. 2015 年五大移动端设计趋势
  11. 华为 21 级程序员月薪曝光:270k 封神!众网友直呼长见识
  12. 迅为i.MX6ULL终结者Mfgtools修改单独只烧写Uboot,内核,文件系统
  13. 《kafka面试100例 -6》如果在/admin/delete_topics/中手动写入一个节点会不会正常删除Topic
  14. docker下mysql主从搭建
  15. 0918 iOS10兼容/iOS系统过高或过低配置包/混合引擎的在线视频连麦互动直播/源码管理工具/Xcode8插件升级/导航栏渐变
  16. Hadoop实战问题记录
  17. 2013年中国android智能手机用户调查研究报告,ZDC:2013年7月中国智能手机市场分析报告...
  18. 数据异质性会影响深度学习变化检测模型的迁移能力,请列出提升模型迁移性的解决思路...
  19. 运算放大器偏置电阻的计算
  20. PR剪辑教学之电影混剪案例

热门文章

  1. Java项目打war包的方法
  2. Matlab如何求离散点的导数
  3. error c4996: 'fopen' This function or variable may be unsafe如何解决
  4. UBUNTU下双显示器设置
  5. 计算机在智慧交通的应用论文,智能交通的毕业论文
  6. 华为堡垒机_运维堡垒机----Gateone
  7. uniapp无法使用substr_关公战秦琼------Excel、SPSS Modler和R的使用对比(下)
  8. 一句话木马绕过linux安全模式,一句话木马(webshell)是如何执行命令的
  9. java 获取oracle mysql sqlserver 链接 connection
  10. php-cli下载,php-cli-color