从导致 ConcurrentModificationException 的 ArrayList 中删除随机项

Remove Random Item From ArrayList Causing ConcurrentModificationException

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

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() 但这只会删除迭代器中的下一个项目,我每次都需要删除一个随机项目.

我的问题是,我是否需要做出一些明显的改变来避免并发问题,或者整个方法是否存在根本性缺陷?

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

当您修改子列表时,您也在修改组列表。因此,如果您在此过程中迭代 groupList,您将得到 ConcurrentModificationExceptions。

听起来您不需要修改groupList(因为您要的是filteredList)。因此,尝试将 subList 设为自己的列表,而不是 groupList 的视图:

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