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

#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. vue2.0 v-model指令

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. 数据层优化-jdbc连接池简述、druid简介

    终于回到既定轨道上了,这一篇讲讲数据库连接池的相关知识,线程池以后有机会再结合项目单独写篇文章(自己给自己挖坑,不知道什么时候能填上),从这一篇文章开始到本阶段结束的文章都会围绕数据库和dao层的优化 ...

  3. CAD使用SetxDataString写数据(com接口)

    主要用到函数说明: MxDrawEntity::SetxDataString 写一个字符串扩展数据,详细说明如下: 参数 说明 [in] BSTR val 字符串值 szAppName 扩展数据名称 ...

  4. Android Bitmap详细介绍(3)

    package com.testbitmapscale; import java.io.File; import java.io.FileInputStream; import java.io.Fil ...

  5. js中5中继承方式分析

    //1.借用式继承   把sup的构造函数里的属性方法克隆一份sub实例对象     function Super(){       this.val = 1;       this.fun1 = f ...

  6. 「 Luogu P2196 」 挖地雷

    # 解题思路 跑 $\text{n}$ 遍 $\text{spfa}$ 并记录路径,找到比当前最长路长的就更新答案,并且将路径也更新,注意起点的处理. # 附上代码 #include <iost ...

  7. KBE实践——登录案例

    目录 服务器 ``` void maini(){ printf("hello world"); } ``` 最小资产库创建 entity配置 实体的Python实现 创建第一个空间 ...

  8. mongodb的安装与简单操作

    MongoDB中文社区:http://www.mongoing.com     数据库的使用场景 SQL(关系型数据库):MySQL.SQLServer  --->磁盘操作 1.高度事务性的场景 ...

  9. [Python3网络爬虫开发实战] 3.1.2-处理异常

    前一节我们了解了请求的发送过程,但是在网络不好的情况下,如果出现了异常,该怎么办呢?这时如果不处理这些异常,程序很可能因报错而终止运行,所以异常处理还是十分有必要的. urllib的error模块定义 ...

  10. Buffer.from()

    Buffer.from(array) array {Array} 使用一个8位字节的数组分配一个新的 Buffer. const buf = Buffer.from([0x62, 0x75, 0x66 ...