我看到一种奇怪的行为.
List<String> li = new ArrayList<>();
li.add("a");
li.add("b");
li.add("c");
li.add("d");
li.add("e");
for(String str:li){
if(str.equalsIgnoreCase("d")){
li.remove(str); //removing second last in list works fine
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试删除列表中的第二个以外的任何其他,我得到ConcurrentModificationException.在阅读"Oracle认证助理Java SE 7程序员学习指南2012"时,我注意到它错误地假设.remove()始终使用删除列表中倒数第二个的示例.
pra*_*nth 13
在列表中,添加或删除被视为修改.在您的情况下,您进行了5次修改(添加).
'for each'循环的工作原理如下,
Run Code Online (Sandbox Code Playgroud)1.It gets the iterator. 2.Checks for hasNext().
public boolean hasNext()
{
return cursor != size(); // cursor is zero initially.
}
Run Code Online (Sandbox Code Playgroud)
3.如果是,请使用next()获取下一个元素.
public E next()
{
checkForComodification();
try {
E next = get(cursor);
lastRet = cursor++;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
final void checkForComodification()
{
// Initially modCount = expectedModCount (our case 5)
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
Run Code Online (Sandbox Code Playgroud)
重复步骤2和3,直到hasNext()返回false.
如果我们从列表中删除一个元素,它的大小会减少并且modCount会增加.
如果我们在迭代时删除一个元素,则modCount!= expectedModCount得到满足并抛出ConcurrentModificationException.
但删除倒数第二个对象很奇怪.让我们看看它在你的情况下是如何工作的.
原来,
cursor = 0 size = 5 - > hasNext()成功,next()也成功,无异常.
cursor = 1 size = 5 - > hasNext()成功,next()也成功,无异常.
cursor = 2 size = 5 - > hasNext()成功,next()也成功,无异常.
cursor = 3 size = 5 - > hasNext()成功,next()也成功,无异常.
在你删除'd'的情况下,大小减少到4.
cursor = 4 size = 4 - > hasNext()不成功,跳过next().
在其他情况下,ConcurrentModificationException将作为modCount!= expectedModCount抛出.
在这种情况下,不会进行此检查.
如果在迭代时尝试打印元素,则只打印四个条目.跳过最后一个元素.
希望我说清楚.
Don List#remove(Object)在这里使用,因为您在for-each循环中访问List中的元素.
而是使用Iterator #remove()从List中删除一个项目:
for(Iterator<String> it=li.iterator(); it.hasNext();) {
String str = it.next();
if(str.equalsIgnoreCase("d")) {
it.remove(); //removing second last in list works fine
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3879 次 |
| 最近记录: |