我有来自文件的行的ArrayList。
文件包含5个数字的行:
1 1 13 25 25
25 25 11 3 1
25 25 13 1 1
我有函数test(String)来测试是否需要此行,或者是否必须从列表中删除它。
我的测试方法:
static boolean test(String s){
return list.contains(reverse(s));
}
reverse(String)返回以相反顺序写入数字的行。
对于
1 1 13 25 25
,它将返回25 25 13 1 1
。因此,我编写了使用Iterator遍历列表和删除元素的代码。
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行)
最佳答案
您在修改列表时在列表上进行遍历(通过调用contains()
),这通常是个坏主意。
您的第一个算法测试列表中是否包含第一行的内容。它删除该行。然后,它检查第二行(现在是第一行),并且找不到反向的行元素,因为第一行已被删除。
第二种算法是不同的:它遍历列表并标记所有必须删除的索引。然后将其全部删除。第二行与第一行相反。同样的第三。所以最后,一切都相反。
尽管此行为未在removeIf中进行记录,但它符合谓词应为等幂的常规合同,此处不是这种情况。在列表元素上调用谓词不会返回相同的值,具体取决于您是否已删除列表的另一个元素。