2012-10-07 136 views
0

这是否会导致不可预知的行为?java arraylist迭代

ArrayList<X> x = new ArrayList<>(); 
//x.add(new X())... 
f: 
for(int i = 0; i < x.size() -1;) 
{ 
     X y = x.get(i); 
     for(int j = i + 1; j < x.size();) 
     { 
      if(a) { 
      x.remove(j); 
      continue; 
      } 
      if(b) { 
      x.remove(i); 
      continue f; 
      } 
      j++; 
     } 
     i++; 
} 
+0

什么是'a'和'b'? –

+0

布尔值依赖于x.get(j)和x.get(i)的值;迭代没有迭代器,仍然是删除问题 –

+0

每次检查'for's'条件时应该调用'x.size()',所以你应该没问题。 – Jon

回答

1

我不认为这将是不可预知的,但你的风格似乎对我来说是错误的,所以你的方法是可疑的。

使用标签是一个坏主意,并决定使用它表明您的方法存在缺陷。

你可能想看看有关删除的ArrayList的讨论,但基本上,LinkedList的是fsster:

http://www.velocityreviews.com/forums/t587893-best-way-to-loop-through-arraylist-and-remove-elements-on-the-way.html

但是,除去这种方式会工作。

UPDATE:

哎呀,刚才看到一对夫妇的bug:

 if(a) { 
     x.remove(j); 
     continue; 
     } 

OK,在这其中,你会回去通过循环对于j,但你并没有增加学家

 if(b) { 
     x.remove(i); 
     continue f; 
     } 

这对我来说是一样的。

所以,你需要一个类似的改变来解决它:

for(int i = 0; i < x.size() -1; i++) 

这样,当你打continue那么它仍然会去到下一个元素。

+0

java.lang.Object.wait(Native Method) java.lang.Object.wait(Object.java:503) java.lang.ref.Reference $ ReferenceHandler.run(Unknown Source) java.lang.Object。等待(Native Method) java.lang.ref.ReferenceQueue.remove(Unknown Source) java.lang.ref.ReferenceQueue.remove(Unknown Source) java.lang.ref.Finalizer $ FinalizerThread.run(Unknown Source)其中一个堆栈跟踪,其余的都被卡在问题中的循环中。所以只是怀疑它可能是错的。 –

+0

我没有看到问题。如果你删除了某些东西,为什么你需要增加。 –

+0

我倾向于从第一个位置移开,从其他位置移出对我来说是一个问题。我认为你可能想重新考虑你的设计,因为它有缺陷,你会浪费时间去修复它,而不是仅仅重新设计它。 –

0

是的。编译器只会优化并调用x.size()一次。因此,删除元素后,终止条件就会变得不正确。

+0

这是一个假设还是你在源代码中看到这个? –

+1

这是我的假设。 – Sameer

1

最好创建一个array,其中包含要删除的索引。 并在主要for周期中用索引填充它。比你可以做这样的事情:

Collections.sort(indexesToRemoveArr); 
Collections.reverse(indexesToRemoveArr); 
for (int indexToRemove : indexesToRemoveArr) { 
    arr.remove((int) indexToRemove); 
} 

在该代码中,我删除索引从结束开始。这就是为什么它不会有任何问题。