我遇到了Java 8 foreach流试图在循环中移动到下一个项目的问题。我不能设置像continue;
这样的命令,只有return;
可以工作,但是在这种情况下你会退出循环。我需要继续循环中的下一项。我怎么能这么做呢?
示例(不工作):
try(Stream<String> lines = Files.lines(path, StandardCharsets.ISO_8859_1)){
filteredLines = lines.filter(...).foreach(line -> {
...
if(...)
continue; // this command doesn't working here
});
}
示例(工作):
try(Stream<String> lines = Files.lines(path, StandardCharsets.ISO_8859_1)){
filteredLines = lines.filter(...).collect(Collectors.toList());
}
for(String filteredLine : filteredLines){
...
if(...)
continue; // it's working!
}
5条答案
按热度按时间kx1ctssn1#
使用
return;
就可以了。它不会阻止整个循环完成。它只会停止执行forEach
循环的当前迭代。尝试以下小程序:
输出量:
一
C
注意
return;
是如何在b
迭代中执行的,但是c
在下一个迭代中打印得很好。为什么会这样?
这种行为起初看起来不直观的原因是因为我们习惯了
return
语句中断整个方法的执行。因此在本例中,我们期望main
方法的执行作为一个整体被停止。然而,需要理解的是,lambda表达式,例如:
...实际上需要被认为是它自己独特的“方法”,完全独立于
main
方法,尽管它方便地位于其中。所以实际上,return
语句只是暂停了lambda表达式的执行。第二件需要理解的事情是:
.实际上只是一个普通的循环,它在每次迭代中都执行lambda表达式。
记住这两点,上面的代码可以用以下等效的方式重写(仅用于教育目的):
有了这个“不那么神奇”的代码等价物,
return
语句的作用域就变得更加明显了。rseugnpd2#
另一个解决方案:通过一个过滤器,用你的反转条件:范例:
可以替换为
最直接的方法似乎是使用“return;”不过。
41zrol4v3#
传递给
forEach()
的lambda将对从流中接收的每个元素进行求值。迭代本身在lambda范围内是不可见的,所以你不能像forEach()
是一个C预处理器宏那样continue
它。相反,您可以有条件地跳过其中的其余语句。yeotifhr4#
您可以使用一个简单的
if
语句来代替continue。所以,你可以尝试以下方法,而不是你的代码:if语句中的 predicate 将与
if(pred) continue;
语句中的 predicate 相反,因此只需使用!
(逻辑非)。k10s72fa5#
可以使用
takeWhile
lambda函数。如果此流是有序的,则返回一个流,该流由取自此流的与给定 predicate 匹配的元素的最长前缀组成。否则,如果此流是无序的,则返回一个流,该流由取自此流的与给定 predicate 匹配的元素的子集组成。
只打印字符串,直到字符串不是
c
。所以它会返回,而不是继续循环。输出量: