打开APP
未登录
开通VIP,畅享免费电子书等14项超值服
开通VIP
首页
好书
留言交流
下载APP
联系客服
[Java拾遗]迭代list过程中删除元素
雪狼11
>《java》
2014.06.18
关注
今天在翻看HDFS中FSImage初始化部分时,其中有段代码是这样的:
Java代码
for (URI dirName : fsNameDirs) {
boolean isAlsoEdits = false;
for (URI editsDirName : fsEditsDirs) {
if (editsDirName.compareTo(dirName) == 0) {
isAlsoEdits = true;
fsEditsDirs.remove(editsDirName);
break;
}
}
}
根据以往经验,这段代码可能会有ConcurrentModificationException发生。在向他们指出这个问题前,我写了简单几句测试代码来提前验证下。
代码一:
Java代码
List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
for (String str : list) {
if (str.equals("a")) {
list.remove(str);
}
}
System.out.println(list);
代码一的结果如预期抛出异常。因为在迭代过程中再去删除元素,会造成迭代索引有问题。于是我又随手修改了下判断条件,删除list不同位置的元素。大家看下面这个例子,它的结果应该是什么?
代码二:
Java代码
List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
for (String str : list) {
if (str.equals("b")) {
list.remove(str);
}
}
System.out.println(list);
代码二的运行结果是正常的:[a, c]。
这让我比较迷惑了。接着试了几次后发现,在一个list中,只有删除倒数第二个元素时是正常的,删除其它位置都会有异常抛出。于是我翻看了AbstractList中的迭代实现,主体是下面这三段代码
Java代码
public boolean hasNext() {
return cursor != size();
}
public E next() {
checkForComodification();
try {
E next = get(cursor++);
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
cursor标示着当前list的索引,不断地与list size比对。如果hasNext返回true,会紧接着执行next方法,在next方法中检查当前list有没有被修改过。
在list迭代过程中,如果删除一个元素,那么size就减一,hasNext提前结束,迭代不会到达list的最后一个元素。也就是说,如果在迭代到list倒数第二个元素时删除此元素,接下来的hasNext会返回false,迭代结束,不会进入next方法中做检查,也就不会出什么问题。而除此之外的其它情况下,hasNext都是true,接下来的next方法检查时会产生异常。
问题让我很疑惑,但分析后的原理很简单。惟一感觉与平时想法不一样的地方是它对hasNext的判断条件有些奇怪。它没有以cursor小于list size来判断,而是取它俩是否相等,在cursor超过size时,又在从list中get元素时施以IndexOutOfBound的弥补。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报
。
打开APP,阅读全文并永久保存
查看更多类似文章
猜你喜欢
类似文章
【热】
打开小程序,算一算2024你的财运
java集合中的一个移除数据陷阱(遍历集合自身并同时删除被遍历数据)
Java集合Collection和泛型
Java迭代 : Iterator和Iterable接口
java提高篇(三十)
Iterator、Iterable接口的使用及详解
简说设计模式——迭代器模式
更多类似文章 >>
生活服务
热点新闻
留言交流
回顶部
联系我们
分享
收藏
点击这里,查看已保存的文章
导长图
关注
一键复制
下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!
联系客服
微信登录中...
请勿关闭此页面
先别划走!
送你5元优惠券,购买VIP限时立减!
5
元
优惠券
优惠券还有
10:00
过期
马上使用
×