java – Collection根据Collection的内容抛出或不抛出ConcurrentModificationException
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – Collection根据Collection的内容抛出或不抛出ConcurrentModificationException,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2964字,纯文字阅读大概需要5分钟。
内容图文
![java – Collection根据Collection的内容抛出或不抛出ConcurrentModificationException](/upload/InfoBanner/zyjiaocheng/714/b8549d43a70b4432b250ef1ae72ea018.jpg)
参见英文答案 > Why is a ConcurrentModificationException thrown and how to debug it 6个
以下Java代码按预期抛出ConcurrentModificationException:
public class Evil
{
public static void main(String[] args) {
Collection<String> c = new ArrayList<String>();
c.add("lalala");
c.add("sososo");
c.add("ahaaha");
removeLalala(c);
System.err.println(c);
}
private static void removeLalala(Collection<String> c)
{
for (Iterator<String> i = c.iterator(); i.hasNext();) {
String s = i.next();
if(s.equals("lalala")) {
c.remove(s);
}
}
}
}
但是下面的示例(仅在Collection的内容上有所不同)执行时没有任何异常:
public class Evil {
public static void main(String[] args)
{
Collection<String> c = new ArrayList<String>();
c.add("lalala");
c.add("lalala");
removeLalala(c);
System.err.println(c);
}
private static void removeLalala(Collection<String> c) {
for (Iterator<String> i = c.iterator(); i.hasNext();) {
String s = i.next();
if(s.equals("lalala")) {
c.remove(s);
}
}
}
}
这将打印输出“[lalala]”.为什么第二个示例在第一个示例执行时抛出ConcurrentModificationException?
解决方法:
简短的回答
因为迭代器的快速失败行为无法保证.
答案很长
您将获得此异常,因为除非通过迭代器,否则在迭代它时无法操作集合.
坏:
// we're using iterator
for (Iterator<String> i = c.iterator(); i.hasNext();) {
// here, the collection will check it hasn't been modified (in effort to fail fast)
String s = i.next();
if(s.equals("lalala")) {
// s is removed from the collection and the collection will take note it was modified
c.remove(s);
}
}
好:
// we're using iterator
for (Iterator<String> i = c.iterator(); i.hasNext();) {
// here, the collection will check it hasn't been modified (in effort to fail fast)
String s = i.next();
if(s.equals("lalala")) {
// s is removed from the collection through iterator, so the iterator knows the collection changed and can resume the iteration
i.remove();
}
}
现在转到“为什么”:在上面的代码中,注意如何执行修改检查 – 删除将集合标记为已修改,下一次迭代检查是否有任何修改,如果检测到集合发生更改则失败.另一个重要的事情是ArrayList(不确定其他集合)不检查hasNext()中的修改.
因此,可能会发生两件奇怪的事情:
>如果在迭代时删除最后一个元素,则不会抛出任何内容
>那是因为没有“next”元素,所以迭代在到达修改检查代码之前结束
>如果删除倒数第二个元素,ArrayList.hasNext()实际上也会返回false,因为迭代器的当前索引现在指向最后一个元素(以前倒数第二个).
>所以即使在这种情况下,删除后也没有“下一个”元素
请注意,这一切都与ArrayList’s documentation一致:
Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.
编辑添加:
This question提供了有关为什么不在hasNext()中执行并发修改检查并且仅在next()中执行的一些信息.
内容总结
以上是互联网集市为您收集整理的java – Collection根据Collection的内容抛出或不抛出ConcurrentModificationException全部内容,希望文章能够帮你解决java – Collection根据Collection的内容抛出或不抛出ConcurrentModificationException所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。