简体   繁体   English

从ArrayList中删除随机项目,导致ConcurrentModificationException

[英]Remove Random Item From ArrayList Causing ConcurrentModificationException

So, I am running into a bit of a snag with my code and I'm not sure why, or how to get around it. 因此,我的代码遇到了一些麻烦,而且我不确定为什么或如何解决它。 I am writing a method that will take a list of objects and filter it based around some rules. 我正在编写一种方法,该方法将获取对象列表并根据一些规则对其进行过滤。 After applying all of the rules, if the list is still over a certain size I need to randomly select items from a specific sublist then and discard the rest. 应用所有规则后,如果列表仍然超过一定大小,则需要从特定子列表中随机选择项目,然后丢弃其余的列表。 The problem I am running into comes from this block of code: 我遇到的问题来自以下代码块:

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));      
    }
}

The filteredList starts with 0 - n groups, and if its size is less than the maximum random groups from a subset are added until it hits that number. filteredList从0开始- n组,如果它的尺寸小于被添加从子集的最大随机组,直到它击中这个数字。

The problem is that when the filteredList.add(subList.remove(randPos)); 问题是,当filteredList.add(subList.remove(randPos)); line is called I get a ConcurrentModificationException error and the program halts. 行被调用,我得到一个ConcurrentModificationException错误,程序停止。

I've looked up what causes this error but all the examples I've seen don't seem to apply to this case. 我查找了导致此错误的原因,但我看到的所有示例似乎都不适用于这种情况。 I am not iterating over either list, I am just running the loop based on the size of one of them. 我没有遍历任何一个列表,我只是根据其中一个的大小运行循环。 Most of what I've seen suggested to fix the ConcurrentModificationException has been to create an Iterator and use remove() but that only removes the next item in the iterator, and I need to remove a random item each time. 我见过的大多数建议修复ConcurrentModificationException都是创建一个Iterator并使用remove()但这只会删除迭代器中的下一个项目,而我每次都需要删除一个随机项目。

My question is, is there some obvious change I need to make to avoid the concurrency issue, or is this whole methodology fundamentally flawed? 我的问题是,为了避免并发问题,我需要做出一些明显的改变吗?还是整个方法都存在根本性的缺陷?

PS There may be some inefficient code or some edge cases that haven't been handled yet. PS可能存在一些效率低下的代码或尚未处理的一些边缘情况。 I am doing TDD and haven't gotten to all of the test cases yet. 我正在执行TDD,还没有涉及所有测试用例。 The current test this is breaking for is when filteredList has a size of 0, and the subList contains every group in the original groupList. 当前的测试,这是打破了当filteredList的大小为0, subList包含了原来的每组groupList. Once this test stops breaking I'll refactor and work on other test cases. 一旦测试停止,我将重构并处理其他测试用例。

When you modify subList you are also modifying groupList. 当您修改subList时,您也在修改groupList。 So if you are iterating over groupList during this process you would get ConcurrentModificationExceptions. 因此,如果在此过程中遍历groupList,则会得到ConcurrentModificationExceptions。

It doesn't sound like you need to modify groupList (since what you are after is the filteredList). 听起来好像不需要修改groupList(因为您所需要的是filteredList)。 So try making subList it's own list rather than a view over groupList: 因此,尝试使subList成为其自己的列表,而不是对groupList的视图:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM