我看到一个奇怪的行为。
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
}
}
但是,如果我尝试删除列表中倒数第二个以外的任何内容,则会收到ConcurrentModificationException。在阅读“
Oracle认证Java SE 7程序员学习指南2012”时引起了我的注意,该指南错误地假定.remove()始终与删除列表中倒数第二个示例一起使用。
在列表中,添加或删除被视为修改。在您的情况下,您进行了5次修改(添加)。
“ for each”循环的工作原理如下:
1.It gets the iterator. 2.Checks for hasNext().
public boolean hasNext()
{
return cursor != size(); // cursor is zero initially.
}
3.如果为true,则使用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();
}
重复步骤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引发。
在这种情况下,不会进行此检查。
如果您尝试在迭代时打印元素,则只会打印四个条目。最后一个元素被跳过。
希望我说清楚。
问题内容: 这是Java代码的片段: 它显示5。但是为什么声明了for循环的声明部分,却没有声明? 在uu上,您将引用2D数组…这不是一项作业。我正在准备Java认证。干杯 问题答案: 由于你是一个。因此,当您对其进行迭代时,您将首先获得,然后可以对该数组进行迭代以获取单个元素。 因此,您的外部循环具有as类型,因此具有该声明。如果您在另一个内循环中进行迭代,则将得到以下类型:-
问题内容: 我想为每个循环做一个,但要使其同步运行。循环的每次迭代都将执行http.get调用,并返回json以将值插入数据库中。问题是for循环异步运行,这导致所有http.gets一次全部运行,并且我的数据库最终没有插入所有数据。我正在使用async- foreach尝试执行我想要的操作它可以做到,但是如果我能以正确的方式做到这一点,我就不必使用它。 和我的模特 问题答案: 我发现在完成每个调
考虑这个简单的例子: 此代码将打印,但是,如果我对每个
问题内容: 我有这样的结构: 我想使用内置方法(在一行中)对整数()求和。 有任何想法吗? 问题答案: 会工作。
问题内容: 学生的姓名(String [])和相应的标记(int [])存储在不同的数组中。 如何使用Java中的每个循环一起遍历两个数组? 一种简单的方法是在同一循环中使用索引变量。有什么好办法吗? 问题答案: 潜在的问题实际上是您应该将两个数组绑定在一起,并且仅跨一个数组进行迭代。 这是一个非常简单的演示-您应该使用getter和setter,还应该使用a 而不是数组,但这证明了这一点:
我对Java中枚举类型中的值()方法是如何工作的有点好奇。如Java规范文档中所见,我们可以在a中为每个循环遍历某个枚举类型的所有值。例如。 我认为对于每个循环,迭代所有值。在这个调用中,我们在每个循环调用中重复调用一个方法,那么它将如何迭代所有枚举类型或值()方法使用某种迭代器。有人能帮我记录下这个方法的实现吗?