java - 在流中使用 Java 8 foreach 循环移至下一项

标签 java java-8

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/

相关文章:

javascript - 如何从 Javascript 将字符串写入标准输出

java - 创建类的数组,将数组中的各个值作为参数传递

Java REGEX 捕获太多

java - Java 中加载图像的高效跨平台方法

java - 如何在android中继续在后台运行前台服务

文本中的 JavaFx TextFields

java - 方法引用转换如何工作?

java - java中常用的接口(interface)方法实现

java - 使用条件变量阻止生产者消费者 Java 实现

java - ConcurrentLinkedDeque的正确使用