枚举是故障保护的。故障安全迭代器将在原始集合的克隆上工作。那它为什么抛出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
}
}查找下面的错误消息
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)发布于 2017-06-05 18:12:31
Collections.enumeration(Collection)将从作为参数传递的集合中创建迭代器:
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的副本:
Enumeration<String> en = Collections.enumeration(new Vector<String>(v));另外,您应该优先考虑List接口和ArrayList实现,而不是Vector (即同步的),并声明备用转换的泛型集合,从而提高代码的类型安全性。
所以它会给出这段代码(我保留了Vector的用法,因为它可能是一个不可修改的约束,但我指定了泛型,因为即使在遗留代码中添加它通常也会更简单):
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
}发布于 2017-06-05 18:10:44
您的枚举在内部使用迭代器。在迭代元素时,您不能使用向量本身来删除项。你必须使用迭代器。但是你没有权限访问它。相反,创建一个迭代器:
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 ):
import java.util.ArrayList;
import java.util.List;更改后的代码:
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,这通常比使用实现更可取。
编辑:
看看你的例子,也许你真正需要的是一个队列:
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());
}输出:
Size: 3
Amit
Raj
Pathak
Size: 0这与您的示例工作方式相同。有关集合的更多信息,请参阅The official Collections Java Trail
发布于 2017-06-05 18:04:58
枚举是故障安全的。
对,是这样。(考虑到一些语言方面的困难。)
故障安全迭代器将在原始集合的克隆上工作。
对,是这样。(考虑到一些语言方面的困难。)
那么它为什么抛出concurrentModificationException?
因为没有涉及到克隆。
克隆在哪里?
https://stackoverflow.com/questions/44366342
复制相似问题