Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 枚举正在引发concurrentModification异常。为什么?_Java - Fatal编程技术网

Java 枚举正在引发concurrentModification异常。为什么?

Java 枚举正在引发concurrentModification异常。为什么?,java,Java,枚举是故障安全的。故障安全迭代器将用于克隆原始集合。那它为什么抛出concurrentModificationException呢?请澄清 请查找我的代码: public static void main(String[] args) { Vector<String> v=new Vector<String>(); v.add("Amit"); v.add("Raj"); v.add("Pathak"); v.add("Sumit

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

请查找我的代码:

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

    }

}
枚举是故障安全的

对。(考虑到一些语言困难。)

故障安全迭代器将用于克隆原始集合

对。(考虑到一些语言困难。)

那它为什么抛出concurrentModificationException呢

因为不涉及克隆


克隆在哪里?

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

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();
    }
}
更改后的代码:

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();
    }
}

这与您的示例的工作原理相同。有关集合的详细信息,请参见集合。枚举(集合)将从作为参数传递的集合创建迭代器:

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();
        }
    };
}
另外,您应该支持
List
接口和
ArrayList
实现,而不是
Vector
(同步),并声明泛型集合,以避免强制转换并提高代码的类型安全性

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

Vector v=new Vector();
v、 添加(“Amit”);
v、 添加(“Raj”);
v、 添加(“Pathak”);
v、 添加(“Sumit”);
v、 添加(“Aron”);
v、 添加(“长途跋涉”);
枚举en=集合。枚举(新向量(v));
while(en.hasMoreElements()){
字符串值=(字符串)en.nextElement();
系统输出打印项次(值);
v、 删除(值);//修改集合
}

您正在使用的枚举方法不受删除方法的支持。创建枚举后,它将测试checkForComodification。因此,当您从向量中删除时,modCount将增加,expectedModCount未修改

 final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
请使用迭代器修改代码

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");

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

        while (it.hasNext()) {
            String value = it.next();
            System.out.println(value);
            it.remove();

        }

    }
publicstaticvoidmain(字符串[]args){
向量v=新向量();
v、 添加(“Amit”);
v、 添加(“Raj”);
v、 添加(“Pathak”);
v、 添加(“Sumit”);
v、 添加(“Aron”);
v、 添加(“长途跋涉”);
迭代器it=v.Iterator();
while(it.hasNext()){
字符串值=it.next();
系统输出打印项次(值);
it.remove();
}
}

Vector和Enumeration已经过时了-改用
ArrayList
Iterator
。是的,如果你想从书籍和教程中学习java,你可能想找到一些在过去几十年内编写的。如果他们在某个学校教你这些东西,2017年,你可能想换个学校。@assylias甚至带有枚举的ArrayList抛出ConcurrentModificationException。我的疑问是,为什么枚举在枚举是故障安全的情况下抛出此异常。您的问题是如何解释
集合。枚举(v)
的作用。你为什么希望它能克隆某些东西?顺便说一下,从
v.elements()
中得到的结果与从
Collections.enumeration(v)
中得到的结果不同
Collections.enumeration(v)
获取迭代器并使用它生成枚举。检查
集合
源代码。我还认为你应该用一种更年轻的方法来学习java。向量通常不再使用。尤其不是在教程中。据我所知,我手头没有任何好的英语教程。但是你应该很快找到一些(但是它已经使用了
迭代器
,因为
集合。枚举
使用了
迭代器
)@David Conrad:这就是重点。这正是我的观点。请仔细阅读我的答案,并思考枚举在内部使用迭代器时会发生什么。看我答案中的第一句话。。。
Size: 3
Amit
Raj
Pathak
Size: 0
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<String> en = Collections.enumeration(new Vector<String>(v));
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
}
 final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
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");

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

        while (it.hasNext()) {
            String value = it.next();
            System.out.println(value);
            it.remove();

        }

    }