0

我在这段代码中得到一个 java.util.ConcurrentModificationException 并且似乎无法理解为什么或修复它。

在 BO 我有这个(权限是 BO 内的数组列表)

public void setPrivilegename(String privilegename) {
    this.privileges.add(privilegename); 
}

List<PrivilegeObjectBO> arraylist = new ArrayList<PrivilegeObjectBO>();if (rs != null)              {
    while (rs.next()) {        
        for (BO bo : arraylist) {
            if (bo.getRolepkey()==rs.getInt("ROLE_PKEY")) {                         
                bo.setPrivilegename(rs.getString("SP.NAME"));

            }else{
                BO newobj = new BO();
                newobj.setRolepriviledgepkey(rs.getInt("PRIVILEGE_PKEY"));
                newobj.setProticolpkey(protocol);                
                newobj.setPrivilegename(rs.getString("SP.NAME"));
                newobj.setRolepkey(rs.getInt("SRP.ROLE_PKEY"));
                arraylist.add(newobj);
            }
        }
    }
}
4

5 回答 5

3

根据ArrayList javadoc

此类的 iterator 和 listIterator 方法返回的迭代器是快速失败的:如果在创建迭代器后的任何时间对列表进行结构修改,除了通过迭代器自己的 remove 或 add 方法之外的任何方式,迭代器将抛出 ConcurrentModificationException。

for (BO bo : arraylist)

上面的 for-each 循环获取列表的迭代器和

  arraylist.add(newobj);

您试图在不使用迭代器自己的方法的情况下修改列表,这会导致ConcurrentModificationException

这是关于可能解决方案的讨论

于 2013-02-06T16:38:16.127 回答
1

在 java 中,当您在迭代集合时修改集合时,您总是会收到 ConcurrentModificationException。

可能的解决方案:对添加或删除的项目使用临时集合,并在迭代完成后添加或删除这些项目。

于 2013-02-06T16:40:14.393 回答
1

您不能ArrayList使用 foreach 同时对其进行迭代和添加元素。

使用迭代器,如下所示:

Iterator<PrivilegeObjectBO> iterator = arraylist.iterator();
while (iterator.hasNext()) {
  ...
}
于 2013-02-06T16:38:11.493 回答
0

Maybe you can take a look at Collections.synchronizedList(List<?>) static method. It should return a thread safe List from the List object given, and you should not get the exception anymore.

Otherwise, you could try (if applicable) to set the method that accesses to the list synchronized, by adding the keyword synchronized in the method declaration.

于 2013-02-06T16:44:10.227 回答
0

其他人已经指出,add-ing to a ArrayListwhile 迭代它是不允许的。

但是无论如何要解决您的问题,您似乎需要在尝试访问整个列表之前对其进行迭代add,因为您的循环似乎正在检查列表中的任何内容是否与您的行匹配以避免重复。在这种情况下,您不想在迭代列表时添加到列表中,因为直到最后您才知道列表是否有重复项。

所以只需遍历并检查是否找到匹配项:

List<PrivilegeObjectBO> arraylist = new ArrayList<PrivilegeObjectBO>();
if (rs != null) {
    while (rs.next()) {

        boolean found = false;
        for (BO bo : arraylist) {
             if (bo.getRolepkey() == rs.getInt("ROLE_PKEY")) {      
                 bo.setPrivilegename(rs.getString("SP.NAME"));
                 found = true;
             }
        }

        if (!found) {
            BO newobj = new BO();
            newobj.setRolepriviledgepkey(rs.getInt("PRIVILEGE_PKEY"));
            newobj.setProticolpkey(protocol);                
            newobj.setPrivilegename(rs.getString("SP.NAME"));
            newobj.setRolepkey(rs.getInt("SRP.ROLE_PKEY"));
            arraylist.add(newobj);
        }
    }
}

除非你真的想为列表中已经存在的BO每个不匹配添加一个新BO的......

于 2013-02-06T16:57:59.717 回答