我有一个Java 8流的问题,试图在循环中继续下一个项目。我无法像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!
}
答案 0 :(得分:183)
使用return;
可以正常使用。它不会阻止完整的循环完成。它只会停止执行forEach
循环的当前迭代。
尝试以下小程序:
public static void main(String[] args) {
ArrayList<String> stringList = new ArrayList<>();
stringList.add("a");
stringList.add("b");
stringList.add("c");
stringList.stream().forEach(str -> {
if (str.equals("b")) return; // only skips this iteration.
System.out.println(str);
});
}
输出:
一个
ç
注意return;
迭代如何执行b
,但c
在下一次迭代中打印就好了。
这种行为最初看起来不直观的原因是因为我们习惯了return
语句来中断整个方法的执行。因此,在这种情况下,我们希望暂停main
方法执行作为一个整体。
然而,需要理解的是lambda表达式,例如:
str -> {
if (str.equals("b")) return;
System.out.println(str);
}
...确实需要被视为自己独特的“方法”,与main
方法完全分开,尽管它方便地位于其中。实际上,return
语句只会暂停lambda表达式的执行。
需要理解的第二件事是:
stringList.stream().forEach()
...实际上只是一个正常的循环,它为每次迭代执行lambda表达式。
考虑到这两点,上述代码可以用以下等效方式重写(仅限教育用途):
public static void main(String[] args) {
ArrayList<String> stringList = new ArrayList<>();
stringList.add("a");
stringList.add("b");
stringList.add("c");
for(String s : stringList) {
lambdaExpressionEquivalent(s);
}
}
private static void lambdaExpressionEquivalent(String str) {
if (str.equals("b")) {
return;
}
System.out.println(str);
}
使用这个“不太神奇”的代码,return
语句的范围变得更加明显。
答案 1 :(得分:2)
将为从流中接收的每个元素评估要传递给forEach()
的lambda。迭代本身在lambda的范围内是不可见的,因此你不能continue
它就像forEach()
是C预处理器宏一样。相反,您可以有条件地跳过其中的其余语句。
答案 2 :(得分:1)
另一种解决方案:使用倒置条件检查过滤器: 示例:
if(subscribtion.isOnce() && subscribtion.isCalled()){
continue;
}
可以替换为
.filter(s -> !(s.isOnce() && s.isCalled()))
最直接的方法似乎是使用“返回”;虽然。
答案 3 :(得分:0)
您可以使用简单的if
语句而不是继续。因此,您可以尝试使用
try(Stream<String> lines = Files.lines(path, StandardCharsets.ISO_8859_1)){
filteredLines = lines.filter(...).foreach(line -> {
...
if(!...) {
// Code you want to run
}
// Once the code runs, it will continue anyway
});
}
if语句中的谓词将与if(pred) continue;
语句中的谓词相反,因此只需使用!
(逻辑不是)。