foreach中使用remove问题
2017-05-24 13:38
148 查看
先贴代码:
List<String> a = new ArrayList<String>();
a.add("1");
a.add("2");
for (String temp : a) {
if ("2".equals(temp)) {
a.remove(temp);
}
}
这段代码运行会抛java.util.ConcurrentModificationException
相反使用如下代码:
List<String> a = new ArrayList<String>();
a.add("1");
a.add("2");
Iterator<String> it = a.iterator();
while (it.hasNext()) {
String temp = it.next();
if ("2".equals(temp)) {
it.remove();
}
}
就会运行正常
再看:
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(1);
list.add(5);
Iterator<Integer> iterator = list.iterator();
int len = list.size();
int index = 0;
while (len > 0 && index <= len) {
Integer value = iterator.next();
if (value == 1) {
iterator.remove();
}
index++;
len = list.size();
}
System.out.println(list);
也是正常的。
可以看出:iterator.remove()方法里面肯定改变了expectedModCount,使其等于modCount的值,然后再次调用iterator.next()方法的时候不会报错。
看看ArrayList里面的源码:
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
再将上述代码修改:
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(1);
list.add(5);
Iterator<Integer> iterator = list.iterator();
list.add(1234);
while (iterator.hasNext()) {
Integer value = iterator.next();
if (value == 1) {
iterator.remove();
}
}
System.out.println(list);
}
会报错。
可以看出:初始化的时候iterator里面expectedModCount值已经为5了,然后执行list.add(1234),modCnt为6,但是expectedModCount还是为5。
所以:
在iterator执行的代码段里面,最好不要混合集合的add和remove操作。集合的add和remove操作,应该在iterator执行的代码端之前或之后。
List<String> a = new ArrayList<String>();
a.add("1");
a.add("2");
for (String temp : a) {
if ("2".equals(temp)) {
a.remove(temp);
}
}
这段代码运行会抛java.util.ConcurrentModificationException
相反使用如下代码:
List<String> a = new ArrayList<String>();
a.add("1");
a.add("2");
Iterator<String> it = a.iterator();
while (it.hasNext()) {
String temp = it.next();
if ("2".equals(temp)) {
it.remove();
}
}
就会运行正常
再看:
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(1);
list.add(5);
Iterator<Integer> iterator = list.iterator();
int len = list.size();
int index = 0;
while (len > 0 && index <= len) {
Integer value = iterator.next();
if (value == 1) {
iterator.remove();
}
index++;
len = list.size();
}
System.out.println(list);
也是正常的。
可以看出:iterator.remove()方法里面肯定改变了expectedModCount,使其等于modCount的值,然后再次调用iterator.next()方法的时候不会报错。
看看ArrayList里面的源码:
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
再将上述代码修改:
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(1);
list.add(5);
Iterator<Integer> iterator = list.iterator();
list.add(1234);
while (iterator.hasNext()) {
Integer value = iterator.next();
if (value == 1) {
iterator.remove();
}
}
System.out.println(list);
}
会报错。
可以看出:初始化的时候iterator里面expectedModCount值已经为5了,然后执行list.add(1234),modCnt为6,但是expectedModCount还是为5。
所以:
在iterator执行的代码段里面,最好不要混合集合的add和remove操作。集合的add和remove操作,应该在iterator执行的代码端之前或之后。
相关文章推荐
- java中foreach语句中使用remove时出现的问题
- 集合已修改;枚举操作可能无法执行。使用foreach 循环删除DataRow的时候的问题! 该死的AcceptChanges() Row.elete() Remove(Row)使用不同。
- List中使用remove出错的问题分析
- mybatis的foreach语句使用问题
- 使用foreach碰到的问题
- 【php】foreach中使用引用引起的问题
- java中使用list.remove需要注意的问题
- 使用Foreach时出现的一个小问题
- ThinkPHP 中 M 方法查询数据库最后使用 find() 导致返回结果集 foreach 数据不对的问题
- foreach 使用&引用赋值要注意的问题
- PHP的foreach中使用引用时需要注意的一个问题和解决方法
- FragmentTranscation使用时remove(),replace()使用无效的问题
- PHP的foreach语句使用引用变量的问题
- PHP中使用foreach引用需要注意的问题
- PHP中使用foreach和引用导致程序BUG的问题介绍
- 使用List的Remove方法时想起的小问题
- 一个分别使用std::list的remove和erase的问题
- 嵌套Fragment的使用及遇到The specified child already has a parent. You must call removeView()问题的解决
- 嵌套Fragment的使用及遇到The specified child already has a parent. You must call removeView()问题的解决
- Mybatis使用<foreach collection="***" item="**" open="(" separator="," close=")">问题