注意了!ArrayList 增删千万不要乱用…
2020-03-18 09:24:44来源:博客园 阅读 ()
注意了!ArrayList 增删千万不要乱用…
编程过程中常常需要使用到集合,而ArrayList是我们常常使用的,但是最近在一次删除和增加中出现了一些问题,分享记录下。
分下如下俩段代码
List<String>?arrayList1?=?new?ArrayList<String>();
arrayList1.add("1");
arrayList1.add("2");
for?(String?s?:?arrayList1)?{
if("1".equals(s)){
? arrayList1.remove(s);
? }}
List<String>?arrayList2?=?new?ArrayList<String>();
arrayList2.add("2");arrayList2.add("1");
for?(String?s?:?arrayList2)?{
? if("1".equals(s)){
? arrayList2.remove(s);
? }
}
程序运行结果如下:
arrayList1的remove方法成功执行,
arrayList2的remove方法运行抛出ConcurrentModificationException异常。
我们查看源代码来分析异常原因
因为foreach的本质就是使用迭代器Iterator,所有的Collecation集合类都会实现Iterable接口。
找到ArrayList类的iterator()方法
public?Iterator<E>?iterator()?{
return?new?Itr();
}
迭代器的本质是先调用hasNext()方法判断存不存在下一元素,然后再使用next()方法取下一元素
public?boolean?hasNext()?{
return?cursor?!=?size;
}
@SuppressWarnings("unchecked")
public?E?next()?{
????checkForComodification();
????int?i?=?cursor;
????if?(i?>=?size)
????????throw?new?NoSuchElementException();
????Object\[\]?elementData?=?ArrayList.this.elementData;
????if?(i?>=?elementData.length)
????????throw?new?ConcurrentModificationException();
????cursor?=?i?+?1;
????return?(E)?elementData\[lastRet?=?i\];
}
上面arraylist1为什么能remove成功呢?其实它只循环了一次,所以成功了。
因为它在remove元素1之后,它的size-1变成1,然后Itr内部的cursor变量由0变成1,此时1=1,循环结束,所以成功了。
arraylist2为什么remove失败呢?因为它在循环第二次的时候,也remove成功了,但是第三次判断next的时候cursor的值为2导致不等于现在的size 1,所以执行了next方法,最重要的来了,之前remove的操作导致ArrayList的modCount值加1,然后Itr类中的expectedModCount保持不变,所以会抛出异常。
final?void?checkForComodification()?{
if?(modCount?!=?expectedModCount)
throw?new?ConcurrentModificationException();
}
同理可得,由于add操作也会导致modCount自增,所以不允许在foreach中删除, 增加,修改ArrayList中的元素。
对此,推荐大家使用迭代器Iterator删除元素。
Iterator<String>?ite?=?arrayList2.iterator();
while(ite.hasNext())?{
if("1".equals(ite.next()))?{
ite.remove();
}
}
如果存在并发操作,还需要对Iterator进行加锁操作。
作者:奋斗的小程序员
https://www.toutiao.com/i6754322606561690116/
推荐去我的博客阅读更多:
1.Java JVM、集合、多线程、新特性系列教程
2.Spring MVC、Spring Boot、Spring Cloud 系列教程
3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程
4.Java、后端、架构、阿里巴巴等大厂最新面试题
生活很美好,明天见~
原文链接:https://www.cnblogs.com/javastack/p/12515934.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- Mybaties简单实例测试及注意问题 2020-06-07
- 数据结构:用实例分析ArrayList与LinkedList的读写性能 2020-06-04
- 常用API - Scanner、Random、ArrayList 2020-05-31
- 读了这一篇,让你少踩 ArrayList 的那些坑 2020-05-29
- 写代码注意了,打死都不要用 User 这个单词 2020-05-22
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash