有没有一种方法,这个代码可以在没有迭代器的情况下失败?

时间:2016-02-02 15:26:18

标签: java

如果你有

for(int i = 0; i<arrayList.size(); i++)
          arrayList.remove(i);

这有什么问题,我读到从arraylist中删除时需要使用迭代器,以便没有异常。我不明白为什么上面的代码不适合迭代器。大小会随着删除而改变,那么如何抛出异常呢?

2 个答案:

答案 0 :(得分:6)

使用上述代码删除元素i的问题在于您跳过元素。

对于以下内容,我认为这已经纠正了#34;代码:

for(int i = 0; i<arrayList.size(); i++)
      arrayList.remove( i );

假设一个包含元素"a","b","c","d"的列表。

现在让我们检查迭代:

  1. i = 0arrayList.size() = 4 - &gt;我们删除索引0处的元素"a"
  2. i = 1arrayList.size() = 3 - &gt;我们删除索引1处的元素"c"(索引0是"b"
  3. i = 2arrayList.size() = 2 - &gt;我们停止
  4. 有两种方法可以解决这个问题:

    • 从不递增i,即它总是为0(编辑:在这种情况下,您可以使用带有条件{{的while循环1}}并始终删除第一个元素,即arrayList.size() > 0
    • 向后移除,即从remove(0)开始并递减arrayList.size() - 1,直至达到低于0的值。

    如果您正在使用foreach(即您隐式使用迭代器),那么使用任何值调用i将导致remove(i),因为您基本上可以执行与上面描述的类似的操作(跳过元素)因此迭代器在迭代时检查任何修改(通常由列表中的修改计数器和迭代器中值的快照完成)。

    使用显式迭代器(即ConcurrentModificationException)并在迭代器上调用for( Iterator<String> itr = arrayList.iterator(); ...将阻止它,因为迭代器和列表都会收到修改通知,并且可以对它做出正确的反应。

答案 1 :(得分:1)

这不会引发异常:

for(int i = 0; i<arrayList.size(); i++)
    arrayList.remove(i);

这将删除列表中的一半元素(元素0,2,4等)。如果要删除给定范围内的所有元素,请让计数器向后工作或根本没有计数器,并在索引0处删除。如果要删除所有项目,只需使用clear()

然而,像这样......

for(Object o : arrayList)
    arrayList.remove(o);

...将抛出异常,因为您在迭代时修改列表。在这种情况下,您将需要一个迭代器。