List.remove奇怪的行为 [英] List.remove strange behaviour
问题描述
注意:此问题不可重复:为什么我没有得到Java?在这个示例中是.util.ConcurrentModificationException?.问题是,为什么未抛出异常 .
Note: Not a duplicate of this question: Why am I not getting a java.util.ConcurrentModificationException in this example?. The question is, why the exception is not being thrown.
如果我们在 List< String>
上使用 foreach
并尝试从中删除任何元素,那么它将抛出 java.util.ConcurrentModificationException
,但是为什么下面的代码不会引发相同的异常,也不会处理 User
的第二个对象?
If we use foreach
on List<String>
and try to remove any element from it then it throws java.util.ConcurrentModificationException
but why following code is not throwing the same exception and also not processing 2nd object of User
?
public class Common {
public static void main(String[] args) {
User user1 = new User();
user1.setFirstname("Vicky");
user1.setLastname("Thakor");
User user2 = new User();
user2.setFirstname("Chirag");
user2.setLastname("Thakor");
List<User> listUser = new ArrayList<User>();
listUser.add(user1);
listUser.add(user2);
int count = 0;
for (User user : listUser) {
System.out.println(count + ":" + user.getFirstname()+" "+ user.getLastname());
count++;
listUser.remove(user);
}
}
}
输出为:
0:Vicky Thakor
0:Vicky Thakor
推荐答案
Although the question is not an exact duplicate, the linked question: Why am I not getting a java.util.ConcurrentModificationException in this example? contains the answer.
在调用迭代器的 next()
方法时进行检查是否抛出异常,但这仅在 hasNext()
返回 true
.在您的情况下,当列表包含两个元素并且您在第一次迭代中删除了第一个条件时:
The check that verifies whether to throw the exception is made when the next()
method of the iterator has called, but this happens only if hasNext()
returns true
. In your case, when the list has two elements and you remove the first one in the first iteration the condition:
public boolean hasNext() {
return cursor != size(); // 1 != 1 after first iteration
}
偶然是 false
,因为 cursor
位于 1
,而这正是 size()
所在的位置片刻.因此,不会调用 next()
,并且不会引发异常.
is accidentally false
, because cursor
is at 1
and that's what size()
is, at the moment. So next()
is not called, and the exception is not being thrown.
添加第三个元素:
listUser.add(user2);
,将引发异常.但是,您不应依赖该行为,因为作为文档解释,并不能保证:
and the exception will be thrown. However, you should not rely on that behavior, because, as the documentation explains, it is not guaranteed:
请注意,不能保证快速故障行为,因为通常来说,在存在不同步的并发修改的情况下,不可能做出任何严格的保证.快速失败操作会尽最大努力抛出ConcurrentModificationException.因此,编写依赖于此异常的程序的正确性是错误的:ConcurrentModificationException应该仅用于检测错误.
Note that fail-fast behavior cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast operations throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: ConcurrentModificationException should be used only to detect bugs.
这篇关于List.remove奇怪的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!