博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
对List遍历过程中添加和删除的思考
阅读量:7051 次
发布时间:2019-06-28

本文共 2170 字,大约阅读时间需要 7 分钟。

对List遍历过程中添加和删除的思考

平时开发过程中,不少开发者都遇到过一个问题:在遍历集合的的过程中,进行add或者remove操作的时候,会出现2类错误,包括:

java.util.ConcurrentModificationException for in遍历过程中add/remove导致的错误
java.lang.IndexOutOfBoundsException 越界错误,for循环的时候删除元素。
最佳实践

add操作:利用原生的for循环。remove操作利用foreach操作。如下所示:

//OK,利用 iterator 和 其remove 方法
@Test
public void testIteratorRemove2() {
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
if ("3".equals(iterator.next())) {
iterator.remove();
}
}
System.out.println(list);
}

//OK 利用for循环。

@Test
public void testForAdd() {
for (int i = 0, length = list.size(); i < length; i++) {
if (list.get(i).equals("2")) {
list.add("2");
}
}
}
经典错误1

如下代码本意是:通过iterator的方式从头到尾变遍历list中的元素。

@Test
public void testIteratorRemove2() {
while (list.iterator().hasNext()) {
System.out.println(list.iterator().next());
}
}
但是该段代码永远都会输出 list的第一元素,为什么?关键错误在链式写法上:
while (list.iterator().hasNext()) {}
每次循环时候先调用了list.iterator() 在该方法中每次都是重新new了一个新的对象
public Iterator<E> iterator() {
return new Itr();
}
所以每一次都是一个新的遍历对象,所以输出第一个元素。
那么为什么每次都要new一个新的Itr()?我猜想应该是为了并发的读,每次读的都是一份独立的数据,避免多个并发读的时候,出现当前指针问题。
处理办法:将list.iteraotr() 放在外面即可,保证循环中循环的是1个对象。
@Test
public void testIteratorRemove2() {
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
if ("3".equals(iterator.next())) {
iterator.remove();
}
}
System.out.println(list);
}
经典错误2

// 死循环

@Test
public void testForAdd2() {
for (int i = 0; i < list.size(); i++) {
if (list.get(i).equals("3")) {
list.add("3");
}
}
}
当if条件满足的时候,该方法永远不会结束,为什么?
对于for循环 for (int i = 0; i < list.size(); i++)有3个部分,第一个部分为初始化,只执行一次。第二个部分每次都会执行,第三个部分也是每次都会执行。
上述问题的第二步会导致无限循环:因为for中每一次循环都会在list添加了一个元素,每次步进为1,内部元素也是每次都加1.
如何处理该问题: list.size()放在第一部分,第一部分只初始化一次。
//OK 利用for循环。
@Test
public void testForAdd() {
for (int i = 0, length = list.size(); i < length; i++) {
if (list.get(i).equals("2")) {
list.add("2");
}
}
}
经典错误3

//java.lang.IndexOutOfBoundsException: Index: 2, Size: 2

@Test
public void testForRemove() {
for (int i = 0, length = list.size(); i < length; i++) {
if (list.get(i).equals("3")) {
list.remove("3");
}
}
}
该错误在list.add("3")的时候就不会发生该错误,具体原因是什么?
Liu CF:转载请保留原文链接,3Q!

转载于:https://www.cnblogs.com/LiuChunfu/p/8482882.html

你可能感兴趣的文章
阿里云Tech Insight,云上技术者的任意门
查看>>
一次曲折的下载经历
查看>>
岌岌可危 中立之争决定云计算未来
查看>>
一些DX的资源
查看>>
使用NGINX Plus负载均衡Kubernetes服务
查看>>
iOS app设备日志查看
查看>>
阿里云游戏服务器价格-阿里云游戏服务器多少钱
查看>>
Gigamon全面产品系列增强技术领先优势
查看>>
免费申请基于飞腾硬件平台上的麒麟云试用!
查看>>
Linux内核通用队列的使用笔记(读linux内核设计与实现)
查看>>
摩拜AI大数据平台“魔方”发布黄金周骑行预测,加州开发 AI 智能公寓
查看>>
javascript的队列,优先队列,循环队列
查看>>
企业加快云计算应用的十大理由
查看>>
ACID
查看>>
centOS6.4 oracle11g RAC搭建
查看>>
ZABBIX作集中式NGINX性能监控的注意要点
查看>>
《数据虚拟化:商务智能系统的数据架构与管理》一 2.9 报告和分析的新形式...
查看>>
2017年Q2美国新增光伏装机2.4GW 同比增长8%
查看>>
中国人工智能学会通讯——一张图看懂BP算法 1.4 致谢
查看>>
《社交网站界面设计(原书第2版)》——第2章 2.0社交的核心
查看>>