写点什么

Java8 lambda 表达式 forEach 如何提前终止?

作者:Java你猿哥
  • 2023-05-03
    湖南
  • 本文字数:1609 字

    阅读完需:约 5 分钟

Java8 lambda 表达式 forEach 如何提前终止?

首先,让我们看一下 Java 8 中如何使用 forEach()方法。forEach()方法接受一个 Consumer 接口作为参数,该接口定义了一个 accept()方法,该方法接受一个对象并对其执行一些操作。因此,我们可以通过 Lambda 表达式来实现 Consumer 接口。下面是一个使用 Lambda 表达式的 forEach()方法的示例:

List<String> list = Arrays.asList("Java", "C++", "Python", "JavaScript");list.forEach(s -> System.out.println(s));
复制代码

在上面的代码中,我们创建了一个包含四个字符串的列表,并使用 Lambda 表达式来打印每个字符串。

public static void main(String[] args) {    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);    list.forEach(i -> {        if (i == 3) {           return;        }        System.out.println(i);    });}
复制代码


可以看出 return 没有起到作用,这是为什么?

然而,在某些情况下,我们可能需要在 forEach()方法执行到某个元素时提前终止它的执行。在 Java 8 之前,我们可以使用 break 语句来实现这一点。但是,在 Lambda 表达式中,我们不能使用 break 语句。那么,在 Lambda 表达式中如何提前终止 forEach()方法的执行呢?

使用 Lambda 表达式的 forEach 方法提前终止迭代

在某些情况下,我们希望在某个条件满足时提前终止迭代过程,以避免不必要的计算和资源浪费。那么,在这种情况下,我们可以使用 Lambda 表达式的 forEach 方法提前终止迭代。


为了实现提前终止迭代,我们可以在 Lambda 表达式中使用 break 语句来实现。但是,在 Java8 中,Lambda 表达式并不支持使用 break 语句,所以我们需要使用其他的方式来实现提前终止迭代。


一种常见的方式是使用 AtomicBoolean 类型的变量作为标志来实现提前终止迭代。具体实现如下:

csharpCopy codeList<Integer> list = Arrays.asList(1, 2, 3, 4, 5);AtomicBoolean found = new AtomicBoolean(false);list.forEach(i -> {    if (i == 3) {        found.set(true);    }    if (found.get()) {        return;    }    System.out.println(i);});
复制代码

在上面的示例中,我们首先定义了一个 AtomicBoolean 类型的变量 found 作为标志。在 Lambda 表达式中,当元素为 3 时,我们将 found 标志设置为 true,表示已经找到了满足条件的元素。接着,在每次迭代中,我们都会检查 found 标志是否已经为 true,如果是,则直接返回,从而提前终止迭代。如果不是,则继续执行后续操作。

使用自定义的函数式接口来实现提前终止迭代

public interface BreakableConsumer<T> extends Consumer<T> {    boolean isBreak();} public static <T> void forEachWithBreak(List<T> list, BreakableConsumer<? super T> action) {    for (T t : list) {        action.accept(t);        if (action.isBreak()) {            break;        }    }} public static void main(String[] args) {    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);    forEachWithBreak(list, i -> {        if (i == 3) {            return true;        }        System.out.println(i);        return false;    });}
复制代码

在上面的示例中,我们首先定义了一个自定义的函数式接口 BreakableConsumer,它继承了 Consumer 接口,并新增了一个 isBreak 方法,用于判断是否需要提前终止迭代。接着,我们定义了一个 forEachWithBreak 方法,该方法接受一个 BreakableConsumer 类型的参数,并在迭代过程中判断是否需要提前终止迭代。最后,在 main 方法中,我们使用 forEachWithBreak 方法并传递一个 Lambda 表达式作为参数来进行迭代操作。

为什么 foreach 使用 return 语句无法生效?

在 Lambda 表达式中,使用 return 语句无法生效的原因是,Lambda 表达式本身并不是一个独立的代码块,它是一个函数式接口的实现。在 Lambda 表达式中使用 return 语句只会返回当前 Lambda 表达式的执行结果,而不会影响 forEach 方法的迭代过程。因此,如果希望在 Lambda 表达式中提前终止迭代,必须使用其他的方式来实现。


用户头像

Java你猿哥

关注

一只在编程路上渐行渐远的程序猿 2023-03-09 加入

关注我,了解更多Java、架构、Spring等知识

评论

发布
暂无评论
Java8 lambda 表达式 forEach 如何提前终止?_Java_Java你猿哥_InfoQ写作社区