【问题标题】:Remove Random Item From ArrayList Causing ConcurrentModificationException从 ArrayList 中删除随机项导致 ConcurrentModificationException
【发布时间】:2015-06-26 19:55:21
【问题描述】:

所以,我的代码遇到了一些障碍,我不确定为什么,或者如何解决它。我正在编写一种方法,该方法将获取对象列表并根据一些规则对其进行过滤。应用所有规则后,如果列表仍然超过一定大小,我需要从特定子列表中随机选择项目,然后丢弃其余的。我遇到的问题来自这段代码:

List<Group> filteredList = groupList.subList(0, firstMatch);

if(filteredList.size() < MAX_NUM_RETURNED){
    //This sub list is where I need to pull random items from
    List<Group> subList = new ArrayList<Group>();
    subList = groupList.subList(firstMatch, lastMatch); 

    Random rand = new Random();

    while(filteredList.size() < MAX_NUM_RETURNED){
        int randPos = rand.nextInt(subList .size());
        //remove a random group from the sublist and add it to the filtered list
        filteredList.add(subList.remove(randPos));      
    }
}

filteredList 从 0 - n 个组开始,如果其大小小于子集中的最大随机组,则添加直到达到该数量。

问题是,当调用filteredList.add(subList.remove(randPos)); 行时,我收到ConcurrentModificationException 错误并且程序停止。

我查看了导致此错误的原因,但我看到的所有示例似乎都不适用于此案例。我没有遍历任何一个列表,我只是根据其中一个列表的大小运行循环。我所看到的修复ConcurrentModificationException 的大部分建议都是创建一个迭代器并使用remove(),但这只会删除迭代器中的下一个项目,而且我每次都需要删除一个随机项目。

我的问题是,是否需要进行一些明显的更改才能避免并发问题,或者整个方法是否存在根本缺陷?

附:可能有一些效率低下的代码或一些尚未处理的边缘情况。我正在做 TDD,还没有得到所有的测试用例。当前正在中断的测试是 filteredList 的大小为 0,并且 subList 包含原始 groupList. 中的每个组一旦此测试停止中断,我将重构并处理其他测试用例。

【问题讨论】:

  • 你是如何创建filteredLiist的?
  • 在您发布的那个代码块中,您是在迭代filteredList 还是sameCategorySubList?
  • sameCategorySubList 在哪里?我没有在代码中看到它
  • @SudhansuChoudhary 这是一个复制粘贴错误。编辑为sublist。只是将其重命名为与实际代码相比更通用。
  • 如果在下一行替换它,为什么要创建new ArrayList&lt;Group&gt;()

标签: java arraylist concurrentmodification


【解决方案1】:

当您修改 subList 时,您也在修改 groupList。因此,如果您在此过程中迭代 groupList,您将获得 ConcurrentModificationExceptions。

听起来您不需要修改 groupList(因为您所追求的是过滤列表)。所以尝试让 subList 成为自己的列表,而不是 groupList 的视图:

List<Group> subList = new ArrayList<>(groupList.subList(firstMatch, lastMatch));

【讨论】:

  • 工作就像一个魅力。没有意识到子列表仍然与原始列表相关联。谢谢!
猜你喜欢
  • 1970-01-01
  • 2014-12-06
  • 2014-06-03
  • 2019-05-12
  • 2018-07-19
  • 1970-01-01
  • 1970-01-01
  • 2013-12-14
  • 1970-01-01
相关资源
最近更新 更多