首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >枚举引发concurrentModification异常。为什么?

枚举引发concurrentModification异常。为什么?
EN

Stack Overflow用户
提问于 2017-06-05 17:58:36
回答 4查看 624关注 0票数 1

枚举是故障保护的。故障安全迭代器将在原始集合的克隆上工作。那它为什么抛出concurrentModificationException呢?请澄清。

请查找我的代码:

代码语言:javascript
复制
public static void main(String[] args) {

    Vector<String> v=new Vector<String>();
    v.add("Amit");
    v.add("Raj");
    v.add("Pathak");
    v.add("Sumit");
    v.add("Aron");
    v.add("Trek");

    Enumeration en=(Enumeration) Collections.enumeration(v);

    while(en.hasMoreElements())
    {
        String value=(String) en.nextElement();
        System.out.println(value);
        v.remove(value);//modifying the collection

    }

}

查找下面的错误消息

代码语言:javascript
复制
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.Vector$Itr.checkForComodification(Unknown Source)
at java.util.Vector$Itr.next(Unknown Source)
at java.util.Collections$2.nextElement(Unknown Source)
at valar.org.src.EnumerationTest.main(EnumerationTest.java:24)
EN

回答 4

Stack Overflow用户

发布于 2017-06-05 18:12:31

Collections.enumeration(Collection)将从作为参数传递的集合中创建迭代器:

代码语言:javascript
复制
public static <T> Enumeration<T> enumeration(final Collection<T> c) {
    return new Enumeration<T>() {
        private final Iterator<T> i = c.iterator();

        public boolean hasMoreElements() {
            return i.hasNext();
        }

        public T nextElement() {
            return i.next();
        }
    };
}

这意味着迭代器返回到您在迭代器循环中移除元素的集合,并且您不能移除使用迭代器迭代的集合中的元素。

您应该创建在enumeration()调用中传递的Vector的副本:

代码语言:javascript
复制
Enumeration<String> en = Collections.enumeration(new Vector<String>(v));

另外,您应该优先考虑List接口和ArrayList实现,而不是Vector (即同步的),并声明备用转换的泛型集合,从而提高代码的类型安全性。

所以它会给出这段代码(我保留了Vector的用法,因为它可能是一个不可修改的约束,但我指定了泛型,因为即使在遗留代码中添加它通常也会更简单):

代码语言:javascript
复制
Vector<String> v = new Vector<String>();
v.add("Amit");
v.add("Raj");
v.add("Pathak");
v.add("Sumit");
v.add("Aron");
v.add("Trek");

Enumeration<String> en = Collections.enumeration(new Vector<String>(v));

while (en.hasMoreElements()) {
    String value = (String) en.nextElement();
    System.out.println(value);
    v.remove(value);// modifying the collection
}
票数 2
EN

Stack Overflow用户

发布于 2017-06-05 18:10:44

您的枚举在内部使用迭代器。在迭代元素时,您不能使用向量本身来删除项。你必须使用迭代器。但是你没有权限访问它。相反,创建一个迭代器:

代码语言:javascript
复制
public static void main(String[] args) {

    final Vector<String> v = new Vector<String>();
    v.add("Amit");
    v.add("Raj");

    // Use an Iterator to remove the value you are iterating over
    final Iterator<String> iterator = v.iterator();

    while (iterator.hasNext()) {
        final String value = iterator.next();
        System.out.println(value);
        iterator.remove();
    }
}

尽管Vector实际上已经被弃用了。你应该使用列表来代替:

正确列表的导入(不要使用awt.List ):

代码语言:javascript
复制
import java.util.ArrayList;
import java.util.List;

更改后的代码:

代码语言:javascript
复制
public static void main(String[] args) {

    final List<String> v = new ArrayList<>();
    v.add("Amit");
    v.add("Raj");
    v.add("Pathak");

    final Iterator<String> iterator = v.iterator();

    while (iterator.hasNext()) {
        final String value = iterator.next();
        System.out.println(value);
        iterator.remove();
    }
}

还请注意,您可以将接口用作Type,这通常比使用实现更可取。

编辑:

看看你的例子,也许你真正需要的是一个队列:

代码语言:javascript
复制
public static void main(String[] args) {

    final Queue<String> v = new LinkedList<>();
    v.add("Amit");
    v.add("Raj");
    v.add("Pathak");

    System.out.println("Size: " + v.size());
    for (String element = v.poll(); element != null; element = v.poll()) {
        System.out.println(element);
    }
    System.out.println("Size: " + v.size());
}

输出:

代码语言:javascript
复制
Size: 3
Amit
Raj
Pathak
Size: 0

这与您的示例工作方式相同。有关集合的更多信息,请参阅The official Collections Java Trail

票数 1
EN

Stack Overflow用户

发布于 2017-06-05 18:04:58

枚举是故障安全的。

对,是这样。(考虑到一些语言方面的困难。)

故障安全迭代器将在原始集合的克隆上工作。

对,是这样。(考虑到一些语言方面的困难。)

那么它为什么抛出concurrentModificationException?

因为没有涉及到克隆。

克隆在哪里?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44366342

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档