首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java ArrayList并发修改

问Java ArrayList并发修改
EN

Stack Overflow用户
提问于 2011-11-06 21:42:32
回答 2查看 2.2K关注 0票数 0

从我的角度来看,我遇到了一些问题来做好这项工作:

代码语言:javascript
复制
    for(Iterator<Object> i = mylist.iterator(); i.hasNext();) {
        Object obj = i.next();
        ArrayList<Object> newlist = new ArrayList<Object>();
        newlist.add(obj);
        i.remove();
        for(Iterator<Object> in = mylist.iterator(); in.hasNext();) {
            Object next = in.next();
            if (obj != next && (another condition)) {
                newlist.add(next);
                in.remove();
            }
        }
        if (newlist.size() > 2) anotheList.add(newlist);
        else for(Object r : newlist) {
            //mylist get back object:
            mylist.add(r);
        }
    }

我正在尝试一种优雅的方式来做到这一点,而不是越来越多地复制我的列表……

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-11-06 22:12:38

代码当前正在执行的操作如下:

  • 在外部循环的第一次迭代中:
    • 删除第一个元素。
    • 在第一个内循环中,删除第一个元素(我们刚刚删除的元素)中不是'==‘的所有其他元素。
    • 如果我们删除了两个以上的元素,请将它们全部放在某个地方,并将该元素放回该元素的末尾

​

显然,这会在外部循环的第二次迭代中遇到并发修改,因为内部循环已经修改了您在外部循环中迭代的集合。你不能这么做。

但是,更重要的是,该算法没有多大意义。在我看来,这很可能意味着代码没有做你想要做的事情。除非你解释你真正想要实现的是什么,否则我们无法弄清楚真正的问题是什么,以及如何解决它。

我仍然不完全理解您想要实现的目标,但我认为解决方案将涉及以下一项或两项:

  • 将myList的实现类更改为允许并发修改的并发集合类之一;例如,使用以下命令对外部循环执行ConcurrentLinkedDeque.
  • Replace:

while (!myList.isEmpty()) { Object obj = myList.remove(0);... }

后一种补救方法去除了ConcurrentModificationException,前提是在第一个内部循环运行时没有其他东西修改列表。第一种补救方法完全去掉了ConcurrentModificationException,只是不能保证第一个内部循环会在其他地方看到添加的元素。

在这两种情况下,如果循环在处理条目的过程中没有进展,那么您必须考虑如何终止循环。

“大O”复杂性也是一个令人担忧的问题,但在不了解“其他条件”正在做什么的情况下,不可能对其进行表征。

票数 6
EN

Stack Overflow用户

发布于 2011-11-06 22:12:18

我假设你有一个ConcurrentModificationException。

当第二个迭代器对列表进行迭代时,您不能在迭代器中修改该列表。

http://download.oracle.com/javase/6/docs/api/java/util/ConcurrentModificationException.html

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8027371

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档