Java List和递归导致并发修改异常

发布于 2024-12-24 19:11:27 字数 542 浏览 2 评论 0原文

以下函数递归地遍历列表并将其始终除以一半并对子列表执行某些操作。当列表大小为 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;
        }
    }

The following function walks recursively through a list and divide it always by half and do something with the sublists. The recursion breaks when the listsize is 2. I know a concurrent modification exception occurs if I change the list when I iterate over it. But I don't use iterations and it still happens:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

静若繁花 2024-12-31 19:11:27

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

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

You're using addAll() which will iterate over the collection you provide in the argument. Now subList only returns a view onto the original list, so you're trying to add values onto a view of the original list, and iterate over a different part of the original list at the same time. Bang.

If you created a copy of the sublist each time, it should work - although it'll be pretty inefficient.

爱的十字路口 2024-12-31 19:11:27

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

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

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

You get a concurrent modification exception because sublist is backed by the original list:

The returned list is backed by this list, so non-structural changes in the returned list are reflected in this list, and vice-versa. The returned list supports all of the optional list operations supported by this list.

If you would like to avoid an exception, make a copy of the first sublist before modifying it.

花海 2024-12-31 19:11:27

如果您使用的是 ArrayList,您可能需要将其更改为 CopyOnWriteArrayList,或 ConcurrentLinkedQueue

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

希望有帮助。

If you are using ArrayList, you may want to change it to a CopyOnWriteArrayList, or ConcurrentLinkedQueue.

If you are on a Multi-thread environment, you will want to put a synchronized around your Array.

Hope it helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文