ArrayList是java开发时非常常用的类,常碰到需要对ArrayList循环删除元素的情况。这时候大家都不会使用foreach循环的方式来遍历List,因为它会抛java.util.ConcurrentModificationException异常。比如下面的代码就会抛这个异常:

1

2

3

4

5

6

7

8

9

10

11

12

13

List

list = new ArrayList();

list.add("1");

list.add("2");

list.add("3");

list.add("4");

list.add("5");

for

(String

item : list)

{

if

(item.equals("3"))

{

System.out.println(item);

list.remove(item);

}

}

System.out.println(list.size());

那是不是在foreach循环时删除元素一定会抛这个异常呢?答案是否定的。

见这个代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

List

list = new ArrayList();

list.add("1");

list.add("2");

list.add("3");

list.add("4");

list.add("5");

for

(String

item : list)

{

if

(item.equals("4"))

{

System.out.println(item);

list.remove(item);

}

}

System.out.println(list.size());

这段代码和上面的代码只是把要删除的元素的索引换成了4,这个代码就不会抛异常。为什么呢?

接下来先就这个代码做几个实验,把要删除的元素的索引号依次从1到5都试一遍,发现,除了删除4之外,删除其他元素都会抛异常。接着把list的元素个数增加到7试试,这时候可以发现规律是,只有删除倒数第二个元素的时候不会抛出异常,删除其他元素都会抛出异常。

好吧,规律知道了,可以从代码的角度来揭开谜底了。

首先java的foreach循环其实就是根据list对象创建一个Iterator迭代对象,用这个迭代对象来遍历list,相当于list对象中元素的遍历托管给了Iterator,你如果要对list进行增删操作,都必须经过Iterator,否则Iterator遍历时会乱,所以直接对list进行删除时,Iterator会抛出ConcurrentModificationException异常

其实,每次foreach迭代的时候都有两部操作:

iterator.hasNext()

//判断是否有下个元素

item = iterator.next()

//下个元素是什么,并赋值给上面例子中的item变量

hasNext()方法的代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

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();

}

}

这时候你会发现这个异常是在next方法的checkForComodification中抛出的,抛出原因是modCount !=

expectedModCount

modCount是指这个list对象从new出来到现在被修改次数,当调用List的add或者remove方法的时候,这个modCount都会自动增减;

expectedModCount是指Iterator现在期望这个list被修改的次数是多少次。

iterator创建的时候modCount被赋值给了expectedModCount,但是调用list的add和remove方法的时候不会同时自动增减expectedModCount,这样就导致两个count不相等,从而抛出异常。

如果想让其不抛出异常,一个办法是让iterator在调用hasNext()方法的时候返回false,这样就不会进到next()方法里了。这里cursor是指当前遍历时下一个元素的索引号。比如删除倒数第二个元素的时候,cursor指向最后一个元素的,而此时删掉了倒数第二个元素后,cursor和size()正好相等了,所以hasNext()返回false,遍历结束,这样就成功的删除了倒数第二个元素了。

破除迷信,foreach循环遍历的时候不能删除元素不是绝对,倒数第二个元素是可以安全删除的~~(当然以上的思路都是建立在list没有被多线程共享的情况下)

java利用循环打印AVA_ava.util.ArrayList在foreach循环遍历时可以删除元素相关推荐

  1. java动态删除map元素报错_java map使用迭代器遍历时执行删除元素报空指针异常

    我建立了两个Map,其流程是遍历两个map,将map1中value值与map2中相同,但是K值不同的数据查找出来.然后把这条数据从Map2中删除.我使用迭代器在执行移除的时候是报空指针(java.la ...

  2. Java语法糖1:可变长度参数以及foreach循环原理

    语法糖 接下来几篇文章要开启一个Java语法糖系列,所以首先讲讲什么是语法糖.语法糖是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢了,编译期间以特定的 ...

  3. java不进入for_为什么阿里巴巴Java开发手册中强制要求不要在foreach循环里进行元素的remove和add操作?...

    在阅读<阿里巴巴Java开发手册>时,发现有一条关于在 foreach 循环里进行元素的 remove/add 操作的规约,具体内容如下: 错误演示 我们首先在 IDEA 中编写一个在 f ...

  4. 为什么阿里巴巴Java开发手册中强制要求不要在foreach循环里进行元素的remove和add操作...

    在阅读<阿里巴巴 Java 开发手册>时,发现有一条关于在 foreach 循环里进行元素的 remove/add 操作的规约,具体内容如下:"不要在foreach循环里进行 r ...

  5. php for循环逗号,关于php:从foreach循环中删除最后一个逗号

    我使用foreach循环从数据库中回显一些值,如果这有意义的话,我需要从最后一个循环中去掉最后一个逗号. 我的循环很简单,如下所示 foreach($results as $result){ echo ...

  6. 列表和字典循环遍历时的删除问题,集合

    1.for 循环的问题 : for 循环后面也有else,也可以使用break和continue(使用方法跟while一样). while    条件:                   for  ...

  7. java中的for语句格式_Java中foreach循环语句的格式可以写成(        )。

    [其它]1) 了解. 收集.整理 原研哉生平.设计理念及经典代表作 (可交) 2) google baidu 简洁的页面 丰富的变化 收集 (可交 ) [单选题]ABS 塑料通常用于 Jaguar L ...

  8. python循环打印数字三角形_使用for循环打印三角形的星形

    圆形 伙计试试这个...... using System; namespace Fan { class Program { static void Main(string[] args) { int ...

  9. java list 遍历 remove_JAVA中LISt遍历时如何remove元素?

    import java.util.*; public class object { public static void main(String[] args) { String str1 = new ...

最新文章

  1. C#,silverlight中 将颜色字符串的RRGGBB转换成为颜色
  2. c轴 t轴 l轴_气涨轴-气胀轴
  3. uva 11491——Erasing and Winning
  4. java使用三种循环打印99表_编程题:利用for循环打印 9*9 表
  5. 阿里云盘小白羊版 v2.9.19 绿色版
  6. SparkSQL下UDF的使用
  7. [hashmap|空间换时间] leetcode 1 两数之和
  8. 控制led闪烁次数_单片机驱动LED灯的进阶之路
  9. P2610 【[ZJOI2012]旅游】(dfs+树的直径)
  10. 【Latex】Latex小论文模板
  11. React修改图片大小
  12. linux+显卡驱动下载官网下载地址,下载:NVIDIA显卡Linux驱动256.44正式版
  13. 上篇日本人经营之道 一制造轰动效应出奇制胜
  14. 绿米Aara单火开关,ZigBee智能开关和单火线取电技术, 对于单火取电电源和ZIGBEE缩合分析
  15. 比MySQL快839倍!揭开分析型数据库JCHDB的神秘面纱
  16. 【ZZULIOJ】1053: 正弦函数
  17. 处理射手网字幕,方便打印
  18. Java中的String类为什么不可变
  19. PTA(2019年天梯赛-全国总决赛)----彩虹瓶 (25分)
  20. 火狐书签备份_备份和还原Firefox密码列表

热门文章

  1. 淘口令高级版api,淘口令转化api,淘口令api,高级淘口令效果,高级淘口令使用场景
  2. 【UOJ #108】【APIO 2013】TOLL
  3. 据说程序员写完代码是这个样子,99%的人都中枪了
  4. TailWind 使用指南
  5. 基于微信教室实验室预约小程序设计与实现 开题报告
  6. DSP关键字cregister (关于IER,IFR找不到定义)
  7. PDF编辑之加密的PDF文档如何解除密码和进行编辑
  8. 【mac】设置的环境变在重启终端后不生效。
  9. 《C语言程序设计》第五版谭浩强课后答案 第九章《用户自己建立数据类型​》习题答案 (大一大二、考研、计算机二级必看)
  10. 简单几行命令让pip升级