2016-12-05 89 views
2

我有來自文件的行的ArrayList。 文件包含線,5號:Collection.removeIf奇怪地工作

1 1 13 25 25 
25 25 11 3 1 
25 25 13 1 1 

而且我有功能測試(字符串)來測試,如果我需要這行或者如果我必須從列表中刪除。 我的測試方法:

static boolean test(String s){ 
     return list.contains(reverse(s)); 
} 

反向(字符串)返回與寫入順序相反的數字線。 對於1 1 13 25 25它將返回25 25 13 1 1

因此,我編寫了使用迭代器遍歷列表並刪除元素的代碼。

Iterator<String> iter = list.iterator(); 
while(iter.hasNext()){ 
    if(test(iter.next())) 
     iter.remove(); 
} 

此代碼正常工作。 但IDEA說,可以用Collection.removeIf調用替換循環。 所以,我試圖替換上面這行代碼:

list.removeIf(s->test(s)); 

但它給我的空單。爲什麼?有什麼不同?

此外,我試圖刪除使用removeIf包含某些字符的行,它能正常工作。 在這裏您可以看到所有的節目:http://pastebin.com/bWw3cBXg

我的文件http://pastebin.com/mEb5sBBJ(17000〜線)

+3

聽起來很奇怪;從*看*你在做什麼......這似乎是一種有效的方法。因此,您可能需要查看http://stackoverflow.com/help/mcve ...以提供一個小例子,可用於** repro **您的問題。 – GhostCat

+0

你能告訴我們'test'方法嗎? – GurV

+0

Thx爲'test'方法。我仍然希望看到並運行一個完整的示例。 –

回答

3

你通過列表​​迭代(通過調用它),而修改它,這通常是一個壞主意。

您的第一個算法測試列表中是否包含反轉的第一行。它刪除該行。然後檢查第二行(現在的第一行),並且沒有找到反轉的行元素,因爲第一行已經被刪除。

第二種算法是不同的:它遍歷列表並標記必須刪除的所有索引。然後它刪除所有這些。第二行與第一行相反。第三個也一樣。所以最後,一切都會顛倒過來。

雖然這種行爲沒有記錄在removeIf中,但它符合謂詞應該是冪等的一般合約,在此情況並非如此。調用列表元素上的謂詞不會返回相同的值,具體取決於您是否已經移除了列表的另一個元素。

+1

不應該仍然保持'25 25 11 3 1'? –

+0

快速測試證實了您描述的removeIf()的行爲(儘管我無法從文檔中讀取它)。當然在OP的例子中,我會期望它至少刪除比循環更多的元素。 –

+0

@tobias_k是的,確實如此。我讀數據的速度太快了,認爲這條線和第三條線相同。但是我猜這個例子中的數據並不是他得到一個空的結果的實際數據。由於他還沒有發佈完整的測試案例,所以很難知道。 –