Java 枚举正在引发concurrentModification异常。为什么?
枚举是故障安全的。故障安全迭代器将用于克隆原始集合。那它为什么抛出concurrentModificationException呢?请澄清 请查找我的代码: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
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();
}
}