迭代时修改集合中元素的概念?

时间:2011-09-10 14:37:33

标签: java

如果线程在使用故障快速迭代器迭代集合时直接修改集合,我发现了这个语句,迭代器将抛出此异常。在http://download.oracle.com/javase/6/docs/api/java/util/ConcurrentModificationException.html

我发现在代码

下面甚至抛出了并发修改
List<Employee> lista= new ArrayList();
Employee emp1=new Employee();
Employee emp2=new Employee();
Employee emp3=new Employee();
lista.add(emp1);
lista.add(emp2);
lista.add(emp3);
for(Employee emp:lista)
{
emp2.setEmpId(2);
lista.remove(emp2);
}

问题1: - 所以我可以说增强for循环也在内部使用故障快速迭代器吗?虽然我执行下面的代码它工作正常

for(int i=0;i<lista.size();i++)
{
Employee empTemp=lista.get(i);
lista.remove(emp2);         
}
问题2: - 另一个问题是声明何时说出

  

如果线程修改了集合

我的猜测是修改意味着这里删除或添加不是为了更新列表接口的集合内部的元素,同时它还包括对set接口的元素的修改。对?至少我试过的程序是他们的情况。

修改

关于set我怀疑我的上述语句,即当我们尝试在迭代时修改set时它抛出并发修改异常。我尝试了下面的代码,但它没有抛出任何异常

HashSet<Employee> set1= new HashSet();
Employee emp4=new Employee();
Employee emp5=new Employee();
Employee emp6=new Employee();
set1.add(emp4);
set1.add(emp5);
set1.add(emp6);


Iterator iter1=set1.iterator();
while(iter1.hasNext())
{
Employee emp12=(Employee)iter1.next();
System.out.println("");
emp5.setEmpId(2);

}

理想情况下,如果在创建迭代器后的任何时间修改集合,则按照语句 http://download.oracle.com/javase/6/docs/api/java/util/HashSet.html它应该抛出并发修改异常,但事实并非如此。不确定为什么?

2 个答案:

答案 0 :(得分:11)

  

问题1: - 所以我可以说增强for循环也在内部使用失败快速迭代器吗?虽然我执行下面的代码它工作正常

是的,没错。查看已编译的代码,使用javap命令验证这一点,如果您愿意。

  

我的猜测是修改意味着这里删除或添加不是为了更新列表接口的集合内部的元素,同时它还包括对set接口的元素的修改。对?至少我试过的程序是他们的情况。

这是正确的,如果你做emp1.setEmpId(2)或类似的东西,迭代不会失败。

  

...它应该抛出并发修改异常,但事实并非如此。不确定原因?

如果您修改列表,它只会抛出异常。请记住,该列表包含对象的引用。如果修改对象,则引用不会更改,因此列表不会更改。

答案 1 :(得分:2)

除非它是由两个不同的线程访问,否则修改列表中的元素没有危险。你的for不会抛出concurrent modification exception,因为你正在修改集合的元素,而不是集合本身。