【问题标题】:ConcurrentModificationException when trying remove element from list [duplicate]尝试从列表中删除元素时出现 ConcurrentModificationException [重复]
【发布时间】:2015-01-31 20:45:12
【问题描述】:

好吧,我已经阅读了其他帖子,但无法解决我的问题。我的 ManagedBean 中有一个 dataTable (JSF) 绑定。我有一个选定元素的列表,我想删除这些元素,请参阅:

public void removeSelected() {

    for (Map.Entry<Integer, Boolean> entry : registrosSelecionados.entrySet()){
       if (entry.getValue() == true){
           int id = entry.getKey();
           Iterator<Bean> it = beans.iterator();
           while(it.hasNext()){
           Bean b = it.next();
           if (b.getId().equals(id)){
               setBean(b);
               deletar();
           }
           }
       }
    }
    }

我上面的方法调用了另一个名为'deletar()'的方法,见:

 public void deletar() {
    try {


        //Se o bean for nulo então capturamos o bean selecionado no DataTable, se este existir
        if (bean == null){
        if (dataTable == null){
            throw new RuntimeException("O bean é nulo e não há dataTable vinculado ao ManagedBean. A deleção será abortada");
        }
        bean = (Bean) dataTable.getRowData();
        }

        beforeRemove();
        getBoPadrao().delete((AbstractBean) bean);
        addInfoMessage("Registro deletado com sucesso");
        beans.remove(bean);
        bean = null;
        afterRemove();
    } catch (BOException e) {
        addErrorMessage(e.getMessage());
        FacesContext.getCurrentInstance().validationFailed();
    } catch (Exception e) {
        e.printStackTrace();
        logger.error((new StringBuilder()).append("Erro ao deletar: ")
            .append(e.getMessage()).toString());
        FacesContext.getCurrentInstance().validationFailed();
        addErrorMessage((new StringBuilder()).append("Erro ao deletar. ")
            .append(e.getMessage()).toString());
    }
    }

Bean 已从数据库中删除,但尝试从“列表”中删除时出现错误:

Jan 31, 2015 5:38:32 PM com.sun.faces.context.AjaxExceptionHandlerImpl handlePartialResponseError
Grave: java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
    at java.util.ArrayList$Itr.next(ArrayList.java:831)
    at br.com.jwebbuild.mb.BasicCrudMBImpl.removeSelected(BasicCrudMBImpl.java:226)

编辑 1

我试图编辑我的 deletar() 方法,放置一个迭代器来删除元素但没有工作,错误继续。

public void deletar() {
    try {


        //Se o bean for nulo então capturamos o bean selecionado no DataTable, se este existir
        if (bean == null){
        if (dataTable == null){
            throw new RuntimeException("O bean é nulo e não há dataTable vinculado ao ManagedBean. A deleção será abortada");
        }
        bean = (Bean) dataTable.getRowData();
        }

        beforeRemove();
        getBoPadrao().delete((AbstractBean) bean);
        addInfoMessage("Registro deletado com sucesso");

        Iterator<Bean> it = beans.iterator();
        while (it.hasNext()) {
        Bean b = it.next();
        if (b.equals(bean)) {
            it.remove();
        }
        }

        bean = null;
        afterRemove();

【问题讨论】:

  • 这无论如何都与 JSF 无关。它是 Java SE。在迭代该集合时,您不能删除该集合的元素。该功能由迭代器的 remove 方法代替。如答案所示,在这种情况下,您应该使用迭代器的 remove 方法。
  • "请注意,Iterator.remove 是在迭代期间修改集合的唯一安全方法;如果在迭代过程中以任何其他方式修改基础集合,则行为未指定。 "docs.oracle.com/javase/tutorial/collections/interfaces/…

标签: java


【解决方案1】:

你说,

好吧,我已经阅读了其他帖子,但无法解决我的问题。

如果您阅读过其他类似的帖子,那么您应该已经知道您只能删除 with 迭代器,这是您没有做的事情,而这正是您必须做的。

例如,

public void deltar(Iterator<Bean> it, Bean bean) {
   // ..... 
   it.remove();
}

【讨论】:

  • 但是我需要从我的列表中删除这个元素,我该如何解决?
  • @user2776409:当然,使用迭代器来遍历列表。
  • 所以,在方法“deletar()”中使用“beans.remove(b)”我应该创建另一个 beans.iterator 并删除元素?对吗?
  • @user2776409:没有。您必须在 Iterator 对象上调用 remove()(正如我一直在说的那样)。不在豆子上,在it。同样,如果您已经完成了您所说的搜索,这应该是显而易见的,因为它们都会告诉您完全相同的事情。
  • @user2776409:现在您使用不同的迭代器从您用来遍历列表的迭代器中删除。您必须使用完全相同的迭代器,而不是两个不同的迭代器。
猜你喜欢
  • 2019-05-12
  • 2021-12-15
  • 2014-06-03
  • 1970-01-01
  • 2013-04-01
  • 2018-01-09
  • 2019-03-09
  • 1970-01-01
  • 2019-05-12
相关资源
最近更新 更多