【问题标题】:Concepts of modifying the element in collection while iterating?迭代时修改集合中元素的概念?
【发布时间】:2011-11-14 09:42:40
【问题描述】:

我发现如果线程在使用快速失败迭代器迭代集合时直接修改集合,则迭代器将抛出此异常。在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:-另一个问题是语句何时说

如果一个线程修改了一个集合

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

编辑

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

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 它应该抛出并发修改异常,但它没有。不知道为什么?

【问题讨论】:

  • 关于您在问题 1 中的示例:“虽然当我执行下面的代码时它工作正常”您的代码不好,它很恶心。如果您在索引 for 循环中添加/删除元素,您将跳过一些元素或处理其他元素两次。修改集合时迭代器抛出异常,这是一件好事。

标签: java


【解决方案1】:

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

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

我的猜测是,这里的修改意味着删除或添加不是为了更新列表接口集合内的元素,同时它还包括修改集合接口的元素。正确的?至少我尝试过的程序就是这样。

没错,如果你做emp1.setEmpId(2)或类似的事情,迭代不会失败。

...它应该抛出并发修改异常,但它没有。不知道为什么?

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-13
      • 2015-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-13
      相关资源
      最近更新 更多