在嵌套循环中删除项目时出现 ConcurrentModificationException

ConcurrentModificationException when removing item in nested loops

这是我的代码,当我删除一个元素时,我得到了一个ConcurrentModificationException。我不明白为什么 itrGrupo1 会受到删除 itrGrupo2.

中的元素的影响

异常发生在:Instancia inst1=(Instancia) itrGrupo1.next() 第二个 while 完成时。

for (int i=0; i<lstPrimeraAgrupacion.size();i++){

  List grupo1=new ArrayList();
  List grupo2=new ArrayList();
  grupo1=(List) lstPrimeraAgrupacion.get(i);         
  grupo2=(List) lstPrimeraAgrupacion.get(i);         

  Iterator itrGrupo1 = grupo1.iterator();
  while(itrGrupo1.hasNext()) {

      List nuevoGrupo=new ArrayList();

      Instancia inst1=(Instancia) itrGrupo1.next();         
      int edad1=Integer.valueOf(inst1.getEdadH());
      int carnet1=Integer.valueOf(inst1.getCarnetH());
      int antigCli1=Integer.valueOf(inst1.getAntigCli());

      Iterator itrGrupo2 = grupo2.iterator();
      while(itrGrupo2.hasNext()) {

          Instancia inst2=(Instancia) itrGrupo2.next();
          int edad2=Integer.valueOf(inst2.getEdadH());
          int carnet2=Integer.valueOf(inst2.getCarnetH());
          int antigCli2=Integer.valueOf(inst2.getAntigCli());

          if(cond){
              nuevoGrupo.add(inst2);
              itrGrupo2.remove();
          }

      }

      // Put in the final list
      if (!nuevoGrupo.isEmpty()){
          lstNuevosGrupos.add(nuevoGrupo);
      }

  }

}

由于以下几行而存在问题:

List grupo1=new ArrayList();
List grupo2=new ArrayList();
grupo1=(List) lstPrimeraAgrupacion.get(i);         
grupo2=(List) lstPrimeraAgrupacion.get(i);

这行的前两行创建了两个新的 ArrayList,但它们后面的行使 grupo1grupo2 指向相同的现有列表。我觉得这是 grupo2 所需要的,因为您正在 修改 它,看起来这段代码的预期效果是修改 lstPrimeraAgrupacioni第一个子列表。 (我假设 lstPrimeraAgrupacionList<List<Instancia>>,或者 Instancia 对象的子列表列表。)

您的代码主体所做的是在 grupo1 中查找任何符合条件的元素,然后将它们从 grupo2 中移除。但是,如果这两个变量引用相同的 List<Instancia> 对象,那么修改 grupo2 也会更改 grupo1 上的迭代器可以访问的内容,可能会使其处于损坏状态(这就是为什么你有例外)。

现在,有更好的方法来解决遍历列表和删除元素的问题,但是按照您设计代码的方式,影响最小的解决方案是简单地将元素复制到new List,并将其用作旧列表的快照,同时根据需要从实际列表中删除元素。为此,您可以将上面的代码更改为以下内容:

List grupo1=new ArrayList();
List grupo2=null;
grupo1.addAll((List) lstPrimeraAgrupacion.get(i)); // Copies the list into our new ArrayList pointed to by grupo1
grupo2=(List) lstPrimeraAgrupacion.get(i); // Makes grupo2 point to the existing List so we can modify it directly.