我有文件中行的 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中,但它符合谓词应该是幂等的一般契约,但这里的情况并非如此。对列表中的元素调用谓词不会返回相同的值,具体取决于您是否已删除列表中的另一个元素。
关于java - Collection.removeIf 工作很奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40974247/