【问题标题】:ConcurrentModificationException at for each android每个 android 的 ConcurrentModificationException
【发布时间】:2015-07-04 13:48:00
【问题描述】:

我传递了ArraylistParseObject,然后我放了一个foreach 循环以在用户对象不等于null 时提取具有条件的项目。我面临两个问题。 1.如果我通过将不同的数据传递给另一个列表然后将该列表传递给我的适配器来执行以下代码行,我将获得带有数字的随机数据,例如:如果在项目#1上的名称是“MAC”,那么它显示在第 3 项中。

ArrayList<ParseObject> checkRequestedNetArrayList = new ArrayList<ParseObject>();
requestedNetArrayList = (ArrayList<ParseObject>) objects;
MyResponsibilitesActivity.requestedNetArrayList = requestedNetArrayList;
adapterRequest = new GenericAdapter<ParseObject>(
    getApplicationContext(),
    requestedNetArrayList,
    R.layout.requested_trust_net_list_item,
    requestedDataBinder);

requestListView.setAdapter(adapterRequest);

requestedNetArrayList = (ArrayList<ParseObject>) objects;

for(ParseObject object: objects){
    System.out.println(object);
    object.getParseObject("user");
    if(object.has("user")){

        checkRequestedNetArrayList.add(object);

    }else{
        checkRequestedNetArrayList.remove(object);
    }

}

adapterRequest = new GenericAdapter<ParseObject>(
    getApplicationContext(),
    checkRequestedNetArrayList,
    R.layout.requested_trust_net_list_item,
requestedDataBinder);

requestListView.setAdapter(adapterRequest);
  1. 如果我正在执行以下代码行来直接给出同一列表中的项目,我会得到java.util.ConcurrentModificationException

    for(ParseObject object: objects){
    
        if(object.has("user")){
    
            requestedNetArrayList.add(object);
    
        }
    }
    else{
        requestedNetArrayList.remove(object);
    }
    
    adapterRequest = new GenericAdapter<ParseObject>(
        getApplicationContext(),
        requestedNetArrayList,
        R.layout.requested_trust_net_list_item,
        requestedDataBinder);
    
    requestListView.setAdapter(adapterRequest);
    

    }

请帮帮我。

【问题讨论】:

  • 重新格式化第二段代码后,我意识到它甚至都不正确。您的大括号不匹配,并且您有一个 else 构造悬挂在不知名的地方。请修复您的代码,使其至少可以编译。

标签: java android list concurrentmodification


【解决方案1】:

访问时不能从列表中删除元素。 你必须使用迭代器。

无论您在何处移除对象,请使用it.remove();

Iterator<ParseObject> it = objects.iterator();
while(it.hasNext()){
    Object object = it.next();
    //your stuff
    it.remove();
}

我想你可能还想看看这篇关于deep copy 的文章。

更新

由于您想将元素添加到列表中,因此无法直接使用迭代器。现在您遇到了问题,因为您直接将objects 分配给requestedNetArrayList,而不是按以下方式进行:

    ArrayList<ParseObject> requestedNetArrayList = new ArrayList<>(objects);

然后像现在一样遍历objects,然后从中删除或添加到 requestedNetArrayList(你几乎已经在做)。

【讨论】:

  • 感谢您在这里的回答。我只需要知道一件事,你能告诉我如何使用该迭代器添加项目,就像我理解它一样。删除部分但不明白如何在其中添加项目,以及如何进一步传递该列表。
  • 我已经更新了答案。在第一个版本的答案中,我只是想解释为什么你会得到那个例外。只需更改 requestedNetArrayList 的初始化即可解决您的问题。
【解决方案2】:

当您对 Collection 使用 for-each 构造进行迭代时

for (Object x : collection) ...

您已经为该 Collection 隐式创建了 Iterator 对象。此迭代器执行检查:自创建迭代器以来集合是否已更改?如果是,则抛出异常。因此,在迭代器完成之前,您应该避免对您的集合进行任何修改。这意味着,您不应该使用添加和删除。

无论哪种方式,最好通过索引访问 ArrayList,因为它会阻止 Iterator 对象的创建。像这样:

for (int i = objects.size() - 1; i >= 0; i--) {
    ParseObject object = objects.get(i);
    // when iterating from tail to head, you can safely add or remove objects to/from this array list
}

【讨论】:

  • 感谢您的回答。它在 count() 处给出此错误 List 类型的方法 count() 未定义。你能在这里帮忙吗
  • 对不起。我印错了。使用 size() 而不是 count()
  • 我只是改变它。实际上我必须将数据传递给数组列表才能在适配器中传递它。您能否根据我的条件制定一个条件,其中我需要发送带有我的条件的某些数据,例如 object.has("user") 并且在该条件下数据将被添加到数组列表中,以便我可以将其传递给我的适配器
  • 我无法理解您的应用程序的逻辑。我认为您只需要删除 uneccesary 项目,而不需要添加(因为它会导致重复)。所以,只需删除添加分支
  • 感谢您的回复。你是对的,我需要从列表中删除不必要的项目。但我还必须将数组列表传递给我的适配器。这就是为什么我说在将其发送到适配器之前我需要删除这些项目。
【解决方案3】:

而不是将对象的引用分配给requestedNetArrayList, 新建一个内容相同的ArrayList

requestedNetArrayList=new ArrayList<ParseObject>(objects);

然后你可以迭代对象并修改requestedNetArrayList。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-01
    相关资源
    最近更新 更多