我对 Java 8 foreach 流尝试移动到循环中的下一个项目时遇到问题。我不能像 一样设置命令continue;,只能return;工作,但在这种情况下你会退出循环。我需要继续循环中的下一个项目。我怎样才能做到这一点?
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循环的当前迭代。
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在接下来的迭代中打印就好了。
b
c
这种行为起初看起来不直观的原因是因为我们习惯了return中断整个方法执行的语句。所以在这种情况下,我们期望main方法执行作为一个整体被停止。
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语句的范围变得更加明显。