2010-10-15 95 views
7

我非常喜歡Java中的for-each-loop構造(for(T e : iterable)),它可以在任何Iterable<T>上工作,因爲它使得在很多情況下很容易讀取和編寫代碼。Java迭代器和for-each-loop。任何方式來訪問基礎迭代器?

我想知道,如果有什麼辦法可以從這樣的循環訪問基礎迭代器。如果我想使用迭代器中的remove(),這可能是強制性的。

回答

17

不,這個for-each-loop的整個點是抽象出底層的迭代器。

如果你需要它,你必須聲明它。

+1

而且當你聲明它時,如果你打算從列表中刪除項目,它應該是一個ListIterator。 – 2010-10-15 12:52:19

1

改爲使用for循環。

4

不,你不能刪除每個循環中的對象。

用這個代替:

Iterator<Type> it = collection.iterator(); 

while (it.hasNext()) { 
    if (it.next().shouldBeRemoved()) { 
     it.remove(); 
    } 
} 
+3

我一般比較喜歡'for'成語而不是'while'成語,因爲它保持了迭代器的範圍更小。 – dty 2010-10-15 12:26:33

+3

@dty:您希望保持所有變量的範圍儘可能窄。但就我而言,代碼的可讀性是第一位的。我的版本幾乎可以像正常的句子一樣讀取:'迭代器有下一個元素:',而你的看起來很麻煩。所以,如果我們想從這兩種方法中獲益,那麼將代碼提取到一個單獨的方法是值得的。恕我直言,這是我們能解決這個問題的最好方法。 – Roman 2010-10-15 16:35:26

0

修改數據具有錯誤感覺到它,只要創建一個新的可迭代(或集合),並添加你要保持它的物品外,其他時間(有點**

+0

你們從未聽說過函數式編程 – fringd 2013-05-01 14:42:05

1

如果集合相當小,您可以選擇使用該集合的副本進行迭代,如果您希望能夠刪除元素,那麼您將不必採取行動如果你有兩個系列。

for(T e : collection.clone()) 
    if(e.shouldBeRemoved()) 
     collection.remove(); 

更好的是,Apache CollectionUtils(有可能是谷歌的替代品和替代品)提供filter(java.util.Collection collection, Predicate predicate)。這個例子返回整個列表。您可以存儲謂詞以供重用。

CollectionUtils.filter(collection, new Predicate(){ 
     boolean evaluate(Object object){return true;} 
    }); 
1

你是正確的,使用迭代器支持從源集合安全地刪除對象,通過對迭代器本身調用remove()的能力。這裏的要點是避免一個ConcurrentModifiedException,這意味着一個集合在Iterator打開時被修改。有些集合可以讓你在迭代時刪除或添加元素到集合中,但是在Iterator上調用remove()是一種更安全的做法。

但迭代器支持派生和更強大的表弟的ListIterator,只能從列表,支持添加和迭代過程中從列表中刪除,以及通過列表滾動雙向。