2011-11-06 40 views
0

我得到一些问题,让这项工作以及我的方面:Java的ArrayList的并发修改

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

我试图得到一个优雅的方式来做到这一点,而不复制MYLIST越来越多的时间.. 。

+2

你能解释一下你正在做什么,以及为什么这段代码没有做你想做的事情? – unholysampler

+5

这看起来很糟糕...你想做什么?我无法确定,但似乎你正试图从现有列表中的一些元素中创建一个新列表,但这似乎是一个可怕的方式来做到这一点。你能更详细地描述你想完成什么吗? – Lucas

+0

我知道,我已经简化了我的代码,让它更具可读性......我需要做的是从一个大列表中做出一些列表,只保留丢弃的对象。其他完成先决条件的列表将分隔存储在另一个对象中。同时大列表已采取新对象来检查此功能 – Achilleterzo

回答

6

目前什么代码正在做的是:

  • 在外环的第一次迭代:
    • 删除第一个元素。
    • 在第1内部循环,去除不“==”的第一个元素(我们只是删除)
    • 如果我们去掉大于2组的元素所有其他元素,把它们放在别的地方。
    • 否则将元素放回到列表的末尾。

显然,这种跑入在外环的第二次迭代并发修改,因为内循环修改了你的外循环遍历集合。你不能那样做。

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


我还是不明白究竟你想达到什么样的,但我认为该解决方案将涉及以下的一种或两种:

  • 更改实现类的myList到并行收集类别确实允许并发修改;例如ConcurrentLinkedDeque

  • 与此更换外循环:

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

后者补救摆脱的ConcurrentModificationException前提是什么,而第1内部循环运行否则修改的列表。第一种补救措施完全摆脱了ConcurrentModificationException,除了不能保证第一个内部循环会看到添加到别处的元素。

在任何一种情况下,如果在处理条目时没有进度,则必须担心如何终止循环。

“大O”的复杂性也是一个问题,但不可能不理解“其他条件”在做什么。

+0

就像一个纸牌游戏,新的列表是玩游戏,其他人是手中的牌,但我意识到这不能与另一部分代码一起工作,那么我需要返回到我的旧代码,而不需要从除非我玩这个游戏。 – Achilleterzo

+0

我不能使用一段时间,因为“mylist”不会变空 – Achilleterzo

+0

@Achilleterzo - 这就是我的意思是由第二句到最后一句。有办法解决这个问题;例如通过将标记对象放入列表中。 –