java循环删除列表元素
2016-03-21 14:36
435 查看
在循环中删除一个列表元素
考虑下面的代码,迭代过程中删除元素:ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
for (int i = 0; i < list.size(); i++) {
list.remove(i);
}
System.out.println(list);
这段代码的输出是:
[b, d]
这个方法有一个严重的问题。当元素被移除,该列表的大小缩减,元素索引也随之发生了变化。所以,如果你想通过使用索引来删除一个循环内的多个元素,就会导致错误的结果。
你可能猜到可以使用iterator来删除循环中的元素。在Java中的foreach循环的工作原理就像一个iterator。 但是在这里也会发生错误。请看下面的代码:
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
for (String s : list) {
if (s.equals("a"))
list.remove(s);
}
上面的foreach loop代码会抛出一个异常ConcurrentModificationException. 但是下面这段代码不会。
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
Iterator<String> iter = list.iterator();
while (iter.hasNext()) {
String s = iter.next();
if (s.equals("a")) {
iter.remove();
}
}
通过分析ArrayList.iterator()的原代码,我们可以发现next()方法必须要在remove()方法前被调用。在foreach loop中,编译器产生的代码会先调用next()方法,从而产生异常。
以上这段是拷贝过来的。但是我自己去看了源码以及测试过后,发现并不是这样。
不是因为先调用next()方法或者先调用remove()方法导致出错。而是remove()和remove(Object o)之间的差异。查看源码,可以看到remove()方法里有一个“expectedModCount = modCount;”语句;而在remove(Object o)方法是这样的“modCount++;”它没有对expectedModCount做处理,导致在checkForComodification()方法判断“expectedModCount == modCount”时出错。所以不管在什么时候,只要你调用了remove(Object
o)方法,然后又调用了next()方法,都一定会报ConcurrentModificationException这个异常的。上面所说的“上面的foreach
loop”的情况就是属于这一现象。
大家可以试一下将remove()方法摆在next()方法前,是可以用的。
相关文章推荐
- Eclipse中工程如何快速重新定位到新的SVN库?
- java安全(五)带秘钥的消息摘要算法——数字签名
- java常见内存溢出(OOM)解决方案
- 小白Java学习笔记(源自itcast-刘意java视频) 4000
- java中的访问控制权限
- Struts2中Action接收参数的方法
- [Java] Java中可变长参数的使用及注意事项
- springMVC—三种控制器controller
- java查找算法(五)--BFPRT查找算法
- 使用console对javaScirpt进行全面调试-全面分析console用法
- java查找算法(四)--随机查找(Randomized-Select)
- Spring AOP浅析
- java查找算法(三)--二分非递归查找
- Log4j在Java中的使用
- Struts2的Session超时返回登录页面
- JDK源码研究之-----------HashMap AND HashCode
- eclipse右键没有maven菜单
- java查找算法(二)--二分递归查找
- java查找算法(一)--顺序查找
- java 重命名文件名字