5

下面的函数递归地遍历一个列表并将其除以一半并对子列表做一些事情。当 listsize 为 2 时,递归中断。我知道如果在迭代列表时更改列表,则会发生并发修改异常。但我不使用迭代,它仍然会发生:

    private static List<ParticipantSlot> divide(List<ParticipantSlot> list) {
        int n = list.size();

        //do something 

        if (n>2){
            List<ParticipantSlot> l = divide(list.subList(0, n/2-1));
            List<ParticipantSlot> r= divide(list.subList(n/2, n));

            l.addAll(r);
            return l;
        }else{
            return list;
        }
    }
4

3 回答 3

10

您正在使用addAll()which 将迭代您在参数中提供的集合。现在subList只返回原始列表的视图,因此您尝试将值添加到原始列表的视图中,并同时迭代原始列表的不同部分。砰。

如果您每次都创建子列表的副本,它应该可以工作 - 尽管它会非常低效。

于 2012-01-05T15:12:25.127 回答
4

您会得到一个并发修改异常,因为子列表由原始列表支持:

返回的列表由该列表支持,因此返回列表中的非结构性更改会反映在该列表中,反之亦然。返回的列表支持此列表支持的所有可选列表操作。

如果您想避免异常,请在修改第一个子列表之前对其进行复制。

于 2012-01-05T15:11:42.900 回答
3

如果您使用的是 ArrayList,则可能需要将其更改为CopyOnWriteArrayListConcurrentLinkedQueue

如果您在多线程环境中,您将需要synchronized在您的数组周围放置一个。

希望能帮助到你。

于 2012-01-05T15:54:49.053 回答