2009-10-01 37 views

回答

11

你是什麼意思的「過濾」?從列表中刪除某些元素?如果是這樣,你可以使用一個iterator

for(Iterator<MyElement> it = list.iterator(); it.hasNext();) { 
    MyElement element = it.next(); 
    if (some condition) { 
     it.remove(); 
    } 
} 

更新(基於評論):

請看下面的例子來說明迭代是如何工作的。比方說,我們有一個包含「A」和'B的列表:

A A B B A

我們要刪除所有那些討厭的B秒。因此,使用上述循環,代碼將如下工作:

  1. hasNext()?是。下一個()。 element指向1st A.
  2. hasNext()?是。下一個()。 element指向2nd A.
  3. hasNext()?是。下一個()。 element指向1st B. remove()。迭代器計數器不會改變,它仍然指向B所在的位置(從技術上講,這並不完全正確,但在邏輯上就是它的工作原理)。如果你現在再次調用remove(),你會得到一個異常(因爲list元素不再存在)。
  4. hasNext()?是。下一個()。 element指向2nd B.其餘部分與#3相同
  5. hasNext()?是。下一個()。 element指向第3位A.
  6. hasNext()?不,我們完成了。列表現在有3個元素。

更新#2remove()操作上確實迭代器可選 - 但只是因爲它是在底層集合可選。這裏的底線是 - 如果你的集合支持它(以及Java Collection Framework中的所有集合),那麼迭代器也是如此。如果你的收藏不支持它,反正你運氣不好。

+0

@ ChssPly76:感謝名單答覆,是的,我用同樣的意思,但它不會影響迭代當我刪除一個元素時,Iterator中的元素來自同一個INSTANCE。 我想從列表(列表)中刪除元素 –

+1

我敢肯定調用remove()的迭代器會影響到基礎列表。否則就沒有意義了。 – Herms

+0

它肯定會從底層列表中刪除元素。它不會影響迭代,但是 - remove()會在「current」元素(從最後一個'next()'方法調用返回的元素)上被調用,並且它不會改變「current」元素。接下來調用next()將返回列表中的下列元素。 – ChssPly76

0

ChssPly76的答案在這裏是正確的方法 - 但我對你的背後的思想很感興趣,「遍歷索引不是一個好選擇」。在很多情況下 - 通常情況下是ArrayList - 這是非常有效的。 (事實上​​,在arraylist的情況下,我認爲重複調用get(i++)比使用迭代器稍微快一點,儘管遠遠不足以犧牲可讀性。從廣義上講,如果所討論的對象實現了java.util.RandomAccess,那麼通過索引訪問順序元素應該與使用迭代器的速度大致相同。如果它不(例如LinkedList將是一個很好的反例),那麼你是對的;但不要忽略這個選項。

+0

Actaully我說緊靠這一特定情況下,只有.. –

+0

是的,但是這並沒有改變的東西 - 如果此特定情況下,您的列表是一個'ArrayList'(或類似),那麼基於索引的訪問將是**快**(甚至比使用迭代器稍快),所以這是一個不錯的選擇。如果這是一種通用的庫方法,它可能會採用各種列表,但您無法控制這些列表的實現 - 那麼假設(儘管您仍然可以檢查接口實現)將會很糟糕。 –

+0

@dtsazza - 你完全正確的表現(+1)。但是,索引循環的問題是,如果您需要從集合中刪除某些元素,那麼將其混淆非常容易。在for循環中修改索引只是不好的業力;而循環需要額外的外部櫃檯,只是感覺不太乾淨。 – ChssPly76

0

我已經使用公共收藏CollectionUtils的

filter(java.util.Collection collection, Predicate predicate) 

方法取得了成功。

http://commons.apache.org/collections/api-2.1.1/org/apache/commons/collections/CollectionUtils.html#filter(java.util.Collection,%20org.apache.commons.collections.Predicate)

+0

可以請您在這裏闡述你的答案,這將是對我非常有用,以及爲他人在未來 –

+0

它是如此討厭,這些接口是不genericised。這就是爲什麼我喜歡谷歌收藏 – daveb

0

如果你和我一樣,不喜歡改變的集合,而通過它的元素,或者如果迭代器只是不提供刪除的實現,你可以使用臨時集合僅僅收取迭代您要刪除的元素。是的,是的,它的效率不高相比,修改迭代器,但對我來說更清晰明白髮生了什麼:

List<Object> data = getListFromSomewhere(); 
List<Object> filter = new ArrayList<Object>(); 

// create Filter 
for (Object item: data) { 
    if (throwAway(item)) { 
    filter.add(item); 
    } 
} 

// use Filter 
for (Object item:filter) { 
    data.remove(item); 
} 

filter.clear(); 
filter = null;