问题描述
使用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
语句的范围变得更加明显。
解决方法
我对 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!
}