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!
}
最佳答案
使用 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);
});
}
输出:
a
c
注意 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
语句的范围变得更加明显。
关于java - 在流中使用 Java 8 foreach 循环移至下一项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32654929/