我有来自文件的行的ArrayList。 文件包含5个数字的行:
1 1 13 25 25
25 25 11 3 1
25 25 13 1 1
我有功能测试(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行)
答案 0 :(得分:3)
你在修改它时重复遍历列表(通过调用contains()
),这通常是一个坏主意。
您的第一个算法测试第一行(反向)是否包含在列表中。它删除了该行。然后它检查第二行(现在是第一行),并且没有找到反向行元素,因为第一行已被删除。
第二种算法不同:它遍历列表并标记必须删除的所有索引。然后它删除所有这些。第二行与第一行相反。第三个相同。所以最终,一切都逆转了。
虽然removeIf中没有记录这种行为,但它符合谓词应该是幂等的一般契约,这不是这里的情况。在列表的元素上调用谓词并不会返回相同的值,具体取决于您是否已经删除了列表中的其他元素。