之前在使用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集合的元素的更多相关文章

  1. java中使用for循环删除List集合的陷阱

    一直以为是数据库的数据取错了,导致后面for循环出错.慢慢调试之后,发现这原来是一个坑.回到正题 (错误示范:使用for循环删除list集合) for(int i=0;i<list.size() ...

  2. 集合赋值及for循环删除符合条件的元素

    一.Java语言中ArrayList对象能直接赋值给另一个ArrayList对象吗? https://zhidao.baidu.com/question/399214655.html ArrayLis ...

  3. Python笔记:用for循环删除列表中的元素

    for运行过程中会有一个指针来记录当前循环的元素是哪一个,一开始这个指针指向第0个元素,然后获取它,接着删除第0个元素,这时候,原来是第1个的元素会变成第0个,当指针向后移动一次,指向了现在第1个元素 ...

  4. ArrayList之foreach循环删除倒数第二个元素,不触发fail-fast机制

    今天一朋友问了个问题,对于如下一段代码,运行后会有怎样的结果? public class ArrayListTest { public static void main(String[] args) ...

  5. (CSDN 迁移) JAVA循环删除List的某个元素

    若列表中只可能存在一个则可以用简单的循环删除,不多说. 若列表中可能存在多个,尤其是可能有多个连续的需要删除,用简单循环有可能发生异常. 需要使用迭代器(Iterator),两种具体实现: 逻辑上是一 ...

  6. python循环删除list中的元素

    直接上例子: a = [1,2,3,4,5,6] for i in a: a.remove(i) print(a) 返回:[2, 4, 6] 循环a,想删除a的所有元素,但实际确有数据保留了下来,这是 ...

  7. 使用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 ...

  8. Java循环删除集合多个元素的正确打开方式

    首先说下不正确的打开方式: 第一:使用for循环删除集合的元素,示例代码如下 ArrayList<String> list = new ArrayList<String>(Ar ...

  9. Java中循环删除list中元素的方法总结

    印象中循环删除list中的元素使用for循环的方式是有问题的,但是可以使用增强的for循环,然后在今天使用的时候发现报错了,然后去科普了一下,发现这是一个误区.下面我们来一起看一下. Java中循环遍 ...

随机推荐

  1. 用Java实现一个简单的DBMS(总结)

    时间:2020/1/16 写这个DBMS(说DBMS夸张了,应该是一个控制台程序)的起因是数据库实践老师布置的一个大作业,先贴上GitHub地址: https://github.com/machi12 ...

  2. Kafka动态配置实现原理解析

    问题导读 Apache Kafka在全球各个领域各大公司获得广泛使用,得益于它强大的功能和不断完善的生态.其中Kafka动态配置是一个比较高频好用的功能,下面我们就来一探究竟. 动态配置是如何设计的? ...

  3. STM32系列之新建工程模板(三)

    今天,我将记录STM32如何新建一个模板步骤 第一步:首先先新建一个文件夹(英文命名的)——作为工程根目录 第二步;在文件夹中新建一个名为USER的子目录文件 第三步:点击 MDK 的菜单:Proje ...

  4. ros之发布者和订阅者协同工作

    前面的例子显示了单个发布者/单个订阅者的情况,但是一个节点也可以同时是一个发布者和订阅者,或者拥有多个订阅和发布. 实际上,ROS节点最常做的事情是传递消息,并在消息上进行运算. 例doubler.p ...

  5. archlinux+UEFI模式在linux主机下基于KVM-QEMU命令行虚拟机安装笔记

    ArchLinux十分精简,并且具有强大的滚动更新.最近在基于ubuntu的宿主机下通过KVM-QEMU虚拟机安装了archlinux,将过程记录下来以供参考. 1.下载启动盘 1.1.下载archl ...

  6. Vmware初次安装虚拟机需要做的一些网络配置——nat模式与桥接模式

    一.本机设置: 1.首先点击图中红线区域: 2.点击网络适配器  3.会出现如下区域: 4.网卡开启后设置ip地址,此处设置的ip和本机的ip没有关系,设置成你虚拟机里面运行的计算机需要的ip地址网段 ...

  7. 事务特性ACID及隔离级别

    注:例子引用来自:https://www.cnblogs.com/WJ-163/p/6023054.html 事务就是一组原子性的SQL查询,或者说一个独立的工作单元. 银行应用是解释事务必要性的一个 ...

  8. redis命令总结与持久化

    上篇redis文章为大家介绍了redis与它的部署工作.这次我们来说一下redis的操作命令与持久化 一.命令总结 1)String操作 6379> set k1 v1 #设定值 6379> ...

  9. PYTHON 学习笔记1 PYTHON 入门 搭建环境与基本类型

    简介 Python,当然大家听到这个名词不再是有关于像JAVA 一样的关于后台,我们学习Python 的目的在于对于以后数据分析和机器学习AI 奠定基础,Python 在数据分析这一块,可谓是有较好的 ...

  10. LwIP的SNMP学习笔记

    关于这方面的资料网上非常少,做一下笔记. 在LwIP中,在\lwip-1.4.1\src\core\snmp目录下有SNMP相关的c文件,在lwip-1.4.1\src\include\lwip目录下 ...