本文主要想讲述一下我对之前看到一篇文章的说法。假设跟你的想法有出入,欢迎留言。一起讨论。

#3. 在循环中删除一个列表元素

  考虑以下的代码。迭代过程中删除元素:

ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
for (int i = 0; i < list.size(); i++) {
list.remove(i);
}
System.out.println(list);

  这段代码的输出是:

[b, d]

  这种方法有一个严重的问题。当元素被移除,该列表的大小缩减。元素索引也随之发生了变化。所以,假设你想通过使用索引来删除一个循环内的多个元素。就会导致错误的结果。

  你可能猜到能够使用iterator来删除循环中的元素。

在Java中的foreach循环的工作原理就像一个iterator。 可是在这里也会错误发生。

请看以下的代码:

ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
 
for (String s : list) {
if (s.equals("a"))
list.remove(s);
}

  上面的foreach loop代码会抛出一个异常ConcurrentModificationException. 可是以下这段代码不会。

ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
Iterator<String> iter = list.iterator();
while (iter.hasNext()) {
String s = iter.next();
 
if (s.equals("a")) {
iter.remove();
}
}

  通过分析ArrayList.iterator()的原代码,我们能够发现next()方法必需要在remove()方法前被调用。

在foreach loop中。编译器产生的代码会先调用next()方法,从而产生异常。

以上这段是拷贝过来的。可是我自己去看了源代码以及測试过后,发现并非这样。

不是由于先调用next()方法或者先调用remove()方法导致出错。而是remove()和remove(Object o)之间的差异。查看源代码,能够看到remove()方法里有一个“expectedModCount = modCount;”语句;而在remove(Object o)方法是这种“modCount++;”它没有对expectedModCount做处理。导致在checkForComodification()方法推断“expectedModCount == modCount”时出错。

所以无论在什么时候,仅仅要你调用了remove(Object
o)方法,然后又调用了next()方法。都一定会报ConcurrentModificationException这个异常的。

上面所说的“上面的foreach
loop”的情况就是属于这一现象。

大家能够试一下将remove()方法摆在next()方法前,是能够用的。

Java循环中删除一个列表元素的更多相关文章

  1. python循环中对一个列表的赋值问题

    参考:https://www.cnblogs.com/zf-blog/p/10613981.html https://www.cnblogs.com/andywenzhi/p/7453374.html ...

  2. Python删除一个列表元素的方法

    参考资料: https://www.cnblogs.com/xiaodai0/p/10564956.html https://www.cnblogs.com/huangbiquan/articles/ ...

  3. java 在循环中删除数组元素

    在写代码中经常会遇到需要在数组循环中删除数组元素的情况,但删除会导致数组长度变化. package com.fortunedr.thirdReport; import java.util.ArrayL ...

  4. javascript在数组的循环中删除元素

    在开发JavaScript应用的过程中,经常会遇到在循环中移除指定元素的需求. 按照常规的思路,就是对数组进行一个for循环,然后在循环里面进行if判断,在判断中删除掉指定元素即可. 但是实际情况往往 ...

  5. python基础一 ------如何统计一个列表元素的频度

    如何统计一个列表元素的频度 两个需求: 1,统计一个随机序列[1,2,3,4,5,6...]中的出现次数前三的元素及其次数 2,统计一片英文文章中出现次数前10 的单词 两种方法: 1,普通的for循 ...

  6. JavaScript从数组中删除指定值元素的方法

    本文实例讲述了JavaScript从数组中删除指定值元素的方法.分享给大家供大家参考.具体分析如下: 下面的代码使用了两种方式删除数组的元素,第一种定义一个单独的函数,第二种为Array对象定义了一个 ...

  7. 从ACM中删除一个已经创建的Library

    从ACM中删除一个已经创建的Library,无法通过界面操作,须要手工从DB中删除.须要删除的表记录有: RECENTUPDATE 找到字段Name等于该libraryName的那条记录删除掉 del ...

  8. .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter

    林德熙 小伙伴希望保存一个文件,并且希望如果出错了也要不断地重试.然而我认为如果一直错误则应该对外抛出异常让调用者知道为什么会一直错误. 这似乎是一个矛盾的要求.然而最终我想到了一个办法:让重试一直进 ...

  9. js删除一个父元素下面的所有子元素

    比如<div id="ok"><button tpye='button'>111111</button><p>22222</p ...

随机推荐

  1. Apache与IIS端口冲突解决方法

    在安装Apache或者php集成环境包是经常会遇到Apache的80端口被占用导致无法正常启动Apache. Win7可以通过如下方法解决(如果坚持要使用80端口的话): 1.打开"控制面板 ...

  2. libevent学习之网络通信

    服务器端要实现网络通信,肯定会用到socket等函数,这几个函数应该没什么问题.libevent默认情况下是单线程的,可以配置成多线程,每个线程有一个event_base,对应一个struct eve ...

  3. redis 其他特性

    1.消息订阅与发布 subscribe my1 订阅频道 psubscribe my1* 批量订阅频道,订阅以my1开头的所有频道 publish my1 hello 在指定频道中发布消息,返回值为接 ...

  4. 上POJ刷题

    Online Judge系统      Online Judge系统(简称OJ)是一个在线的判题系统.用户可以在线提交给定问题的多种程序(如C.C++.Pascal.Java)源代码,系统对源代码进行 ...

  5. 【Pytorch】关于torch.matmul和torch.bmm的输出tensor数值不一致问题

    发现 对于torch.matmul和torch.bmm,都能实现对于batch的矩阵乘法: a = torch.rand((2,3,10))b = torch.rand((2,2,10))### ma ...

  6. JS如何禁用浏览器的退格键

    <script type="text/javascript"> //处理键盘事件 禁止后退键(Backspace)密码或单行.多行文本框除外 function forb ...

  7. fastclick.js插件使用

    引入插件步骤 ①在HTML页面中添加  <script type='application/javascript' src='/path/to/fastclick.js'></scr ...

  8. java配置日志总结

    log4j 搭建日志环境 简单非maven项目,只需要引入log4j.jar,在类路径下添加log4j.properties即可 简单maven项目,只需要在pom.xml引入dependency,在 ...

  9. [HNOI/AHOI2018]转盘(线段树优化单调)

    gugu  bz lei了lei了,事独流体毒瘤题 一句话题意:任选一个点开始,每个时刻向前走一步或者站着不动 问实现每一个点都在$T_i$之后被访问到的最短时间 Step 1 该题可证: 最优方案必 ...

  10. linux命令 iperf-网络性能测试工具

    博主推荐:更多网络测试相关命令关注 网络测试  收藏linux命令大全 iperf命令是一个网络性能测试工具.iperf可以测试TCP和UDP带宽质量.iperf可以测量最大TCP带宽,具有多种参数和 ...