Collection.removeIf奇怪的工作

时间:2016-12-05 12:24:48

标签: java arraylist

我有来自文件的行的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行)

1 个答案:

答案 0 :(得分:3)

你在修改它时重复遍历列表(通过调用contains()),这通常是一个坏主意。

您的第一个算法测试第一行(反向)是否包含在列表中。它删除了该行。然后它检查第二行(现在是第一行),并且没有找到反向行元素,因为第一行已被删除。

第二种算法不同:它遍历列表并标记必须删除的所有索引。然后它删除所有这些。第二行与第一行相反。第三个相同。所以最终,一切都逆转了。

虽然removeIf中没有记录这种行为,但它符合谓词应该是幂等的一般契约,这不是这里的情况。在列表的元素上调用谓词并不会返回相同的值,具体取决于您是否已经删除了列表中的其他元素。