2016-02-02 152 views
-1

如果你有有沒有一種方法,這段代碼可以失敗沒有迭代器?

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

什麼是錯,我讀了一個迭代器需要從一個ArrayList去除,這樣沒有異常時使用。我不明白爲什麼上面的代碼不會滿足迭代器的要求。大小將相應地改變,因此如何拋出異常?

+0

您需要使用小寫字母'i'而不是大寫字母'I' –

+0

[此問題與您的興趣相關。](http://stackoverflow.com/questions/223918/iterating-through-a-list-avoiding -concurrentmodificationexception-when-removing) – Makoto

+0

如果你向後循環遍歷列表,那麼以這種方式去除元素沒有問題 –

回答

6

使用上面的代碼刪除元素i的問題是您將跳過元素。

對於下文中,我假定這個 「校正」 代碼:

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

假設與元件"a","b","c","d"列表。

現在讓我們來檢查迭代:

  1. i = 0arrayList.size() = 4 - >我們刪除索引0,這是"a"
  2. i = 1arrayList.size() = 3元素 - >我們刪除索引1是"c"元素(指數0是"b"
  3. i = 2arrayList.size() = 2 - >我們停止

有兩種方法來解決:

  • 從未增量i,也就是說,它永遠是0(編輯:在這種情況下,你可以只使用一個while循環與條件arrayList.size() > 0和總是移除第一元件,即remove(0)
  • 向後刪除,即開始在arrayList.size() - 1和遞減i,直到到達一個值低於0

如果您使用的是foreach(即你隱式地使用迭代器),然後調用remove(i)任何值將導致ConcurrentModificationException因爲你基本上可以做一些類似於我上面描述的(跳過元素),因此迭代器在迭代時檢查任何修改(通常由修改計數器完成該列表和迭代器中的值的快照)。

在迭代器上使用顯式迭代器(即for(Iterator<String> itr = arrayList.iterator(); ...)並調用remove()將阻止該操作,因爲迭代器以及列表都會收到修改通知,並且可以對其進行適當的反應。

+0

aha,現在有很多意義。但是你說如果我設置i = arrayList.Size() - 1和i--那麼當我刪除它會照顧整個列表。另外,在刪除中使用索引0而不是我會照顧同樣的問題? –

+0

@ camel-man我不確定我是否會收到您的問題,但我會嘗試:如果您刪除前後移除索引後的元素,請向上移動一個索引。因此,如果你回到前面(i--),你總是刪除最後一個元素,所以這不是問題。使用索引0刪除將工作以及只要你不在循環中增加'i'或者只刪除一半元素(增加'i' +刪除第一個元素基本上相當於一個步長2)。 – Thomas

1

這拋出也不例外:

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

這消除了列表(元素0,2,4,等)的一半的元素。如果要刪除給定範圍內的所有元素,請讓計數器向後工作或完全沒有計數器,並在索引0處刪除。如果要刪除所有項目,請使用clear()

但是,像這樣的東西...

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

...將拋出一個異常,因爲您在修改列表的同時迭代它。在這種情況下,你將需要一個迭代器。

相關問題