我有来自文件的行的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中进行记录,但它符合谓词应为等幂的常规合同,此处不是这种情况。在列表元素上调用谓词不会返回相同的值,具体取决于您是否已删除列表的另一个元素。

09-13 12:12