循环删除List集合的元素
之前在使用list集合循环删除元素的时候,竟然出现了集合内的元素不能删除成功的问题,之后整理了一下,发现大有玄机!
1.如果指定了list的size大小,会出现下标越界异常
List<String> list=new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e"); System.out.println("删除前的list:"+list.toString());
for (int i = 0,len=list.size(); i < len; i++) {
if("c".equals(list.get(i))){
list.remove(i);
}
}
System.out.println("删除后的list"+list.toString());
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 4, Size: 4
因为当删除元素c的时候,list集合大小改变了
2.如果每次都动态的获取list的size,当删除多个元素的时候会出现后面元素删除不成功的问题。
List<String> list=new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
list.add("f"); System.out.println("删除前的list:"+list.toString());
for (int i = 0; i < list.size(); i++) {
if("c".equals(list.get(i))||"d".equals(list.get(i))){
list.remove(i);
}
}
System.out.println("删除后的list"+list.toString());
删除前的list:[a, b, c, d, e, f]
删除后的list[a, b, d, e, f]
经过分析:当list删除元素c的时候,此时的i=2,后面的元素会向前补一位,进行下一次循环的时候,此时list集合中的元素为[a, b, d, e, f],i=3,这样会跳过d,从而导致d元素不能删除成功。
3.增强for循环方式删除元素,java.util.ConcurrentModificationException
List<String> list=new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
list.add("f"); System.out.println("删除前的list:"+list.toString());
for (String s : list) {
if("c".equals(s)){
list.remove(s);
}
}
System.out.println("删除后的list"+list.toString());
Exception in thread "main" java.util.ConcurrentModificationException
删除前的list:[a, b, c, d, e, f]
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at operation.ListRemove.main(ListRemove.java:23)
从错误中可以定位到checkForComodification(ArrayList.java:901)

当modCount和expectedModeCount不相等时就会抛出此异常。
modCount是ArrayList类中的一个成员变量,表示对ArrayList的修改次数
expectedModCount:表示对ArrayList修改次数的期望值,它的初始值为modCount
当循环遍历的时候二者是相等的,但是当执行list.remove()方法后,


可以看到modCount++,元素前移,最后一位置空,但是expectedModCount并没有改变。
这就导致modCount和expectedModCount的值不一致。
删除完再次遍历的时候,


此时就会抛出异常了。
4.正确的删除方式
难道就不能删除了吗???这是不可能的,正确的姿势是什么呢?那就是迭代器--Iterator了
List<String> list=new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
list.add("f");
System.out.println("删除前的list:"+list.toString());
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String next = iterator.next();
if("c".equals(next)){
iterator.remove();
}
}
System.out.println("删除后的list"+list.toString());
删除前的list:[a, b, c, d, e, f]
删除后的list[a, b, d, e, f]
binggo~~~~~~~~~~~完美解决
其实:如果只是删除某一个元素,上面的方法都可以。
如果是循环删除多个,还是用迭代器吧!
不足之处欢迎指正!
循环删除List集合的元素的更多相关文章
- java中使用for循环删除List集合的陷阱
一直以为是数据库的数据取错了,导致后面for循环出错.慢慢调试之后,发现这原来是一个坑.回到正题 (错误示范:使用for循环删除list集合) for(int i=0;i<list.size() ...
- 集合赋值及for循环删除符合条件的元素
一.Java语言中ArrayList对象能直接赋值给另一个ArrayList对象吗? https://zhidao.baidu.com/question/399214655.html ArrayLis ...
- Python笔记:用for循环删除列表中的元素
for运行过程中会有一个指针来记录当前循环的元素是哪一个,一开始这个指针指向第0个元素,然后获取它,接着删除第0个元素,这时候,原来是第1个的元素会变成第0个,当指针向后移动一次,指向了现在第1个元素 ...
- ArrayList之foreach循环删除倒数第二个元素,不触发fail-fast机制
今天一朋友问了个问题,对于如下一段代码,运行后会有怎样的结果? public class ArrayListTest { public static void main(String[] args) ...
- (CSDN 迁移) JAVA循环删除List的某个元素
若列表中只可能存在一个则可以用简单的循环删除,不多说. 若列表中可能存在多个,尤其是可能有多个连续的需要删除,用简单循环有可能发生异常. 需要使用迭代器(Iterator),两种具体实现: 逻辑上是一 ...
- python循环删除list中的元素
直接上例子: a = [1,2,3,4,5,6] for i in a: a.remove(i) print(a) 返回:[2, 4, 6] 循环a,想删除a的所有元素,但实际确有数据保留了下来,这是 ...
- 使用LinkedList类生成一个集合对象,循环加入“小样1”,“小样2”,“小样3”,“小样4”,“小样5”……“小样100”。输出这个集合的大小。再使用循环删除这个集合中所有名字为偶数的对象,比如“小样6”,“小样100”,都是偶数名。最后:循环输出集合中所有的对象,看是否删除成功。
package com.lanxi.demo1_8; import java.util.Iterator; import java.util.LinkedList; public class Test ...
- Java循环删除集合多个元素的正确打开方式
首先说下不正确的打开方式: 第一:使用for循环删除集合的元素,示例代码如下 ArrayList<String> list = new ArrayList<String>(Ar ...
- Java中循环删除list中元素的方法总结
印象中循环删除list中的元素使用for循环的方式是有问题的,但是可以使用增强的for循环,然后在今天使用的时候发现报错了,然后去科普了一下,发现这是一个误区.下面我们来一起看一下. Java中循环遍 ...
随机推荐
- Unreal Engine 4 蓝图完全学习教程(五)—— 关于数组
Ⅰ.数组的含义及使用 数组是能统一保存若干数值的特殊变量.数组可以指定编号.运用其中的值,因此能够有序地管理大量的数据. 首先试图将上次创建的msg变量修改成数组,在细节栏点击修改: 并选择“修改变量 ...
- CSAPP
陆陆续续花了2个月的时间终于把这个久负盛名的CSAPP看完了,不愧为一本名副其实的经典书籍.有种相见恨晚的感觉,以至于从不会写书评的我也情不自禁的想说点什么. 这本书的书名叫"Comput ...
- 机器学习总结-LR(对数几率回归)
LR(对数几率回归) 函数为\(y=f(x)=\frac{1}{1+e^{-(w^{T}x+b)}}\). 由于输出的是概率值\(p(y=1|x)=\frac{e^{w^{T}x+b}}{1+e^{w ...
- Python 进行目标检测
一.前言 从学单片机开始鼓捣C语言,到现在为了学CV鼓捣Python,期间在CSDN.简书.博客园和github这些地方得到了很多帮助,所以也想把自己做的一些小东西分享给大家,希望能帮助到别人.记录人 ...
- Tomcat安装教程及常见错误解决方法
目录 Tomcat安装教程及常见错误解决方法 一.安装前准备 ·熟悉自己电脑的操作系统版本(32位or64位) ·保证电脑上已经装好JDK,并且已经设置好环境变量. 二.Tomcat安装教程(以Tom ...
- Ambari HDP 下 SPARK2 与 Phoenix 整合
1.环境说明 操作系统 CentOS Linux release 7.4.1708 (Core) Ambari 2.6.x HDP 2.6.3.0 Spark 2.x Phoenix 4.10.0-H ...
- iRedmail的php由5.4升级到5.6
安装ireadmail时,自带的php是5.4,打算升级到5.6. 升级前注意备份原来的/etc/php-fpm.d下的www.conf,文件内容如下: [inet] user = nginx gro ...
- vue 信使 ------fetch、axios
fetch 1.什么是fetch 相当于promise 必须写两个then 第一个then返回状态码 返回成json格式 第二个then返回json数据 2.使用方法 $ npm install fe ...
- vue学习(一)项目搭建
首先需要配置node和npm,如果没有安装的话,百度一下安装教程. 如果感觉npm下载速度慢,可以使用淘宝镜像cnpm,链接地址: http://npm.taobao.org/ 安装cnpm npm ...
- 使用Unicode(宽字节字符集);多字节字符集中定义宽字节变量
2012-03-25 14:54 (分类:计算机程序) 2.2 宽字符和C 宽字符不一定是Unicode.Unicode是宽字符集的一种.然而,因为本书的焦点是Windows而不是C执行的理论,所以书 ...