Lambda 表达式如何 capture 外部变量?(表达式.变量.Lambda.capture...)

wufei123 发布于 2024-09-29 阅读(23)

lambda 表达式只能访问外部 final 变量或 effectively final 变量(lambda 执行期间值不变的变量)。如非 final 可通过 capture variable 技术访问外部变量。该技术会创建 final 变量,并将外部变量值赋给它,确保 lambda 可访问并使用该值。

Lambda 表达式如何 capture 外部变量?

Lambda 表达式如何捕获外部变量

Lambda 表达式是 Java 8 中引入的一个强大功能,它允许我们创建匿名函数。虽然 lambda 表达式通常是无状态的,但有时我们可能需要访问外部变量。

Final 变量

Lambda 表达式可以访问其作用域内的 final 变量。例如:

int count = 10;
List<Integer> numbers = Arrays.asList(1, 2, 3);
numbers.forEach(n -> System.out.println(count + n));

非 Final 变量

对于非 final 变量,lambda 表达式可以使用 effectively final 变量。所谓 effectively final 变量,是指 lambda 表达式执行期间其值不会改变的变量。例如:

int count = 10;
StringBuilder sb = new StringBuilder();
numbers.forEach(n -> sb.append(count + n));

在上面的示例中,尽管 count 不是 final 变量,但它被视为 effectively final,因为 lambda 表达式执行期间其值不会改变。

使用 Capture Variable

如果外部变量不是 final 或 effectively final,我们可以使用 Capture Variable 来帮助 lambda 表达式访问它们。Capture Variable 会创建一个 final 变量,并将其初始化为外部变量的值。例如:

int count = 10;
Supplier<Integer> counter = () -> count;
count = 20; // 这不会影响 counter 的结果
System.out.println(counter.get()); // 输出 10

实战案例

使用 Lambda 预排序列表

我们有一个包含 100 万个整数的列表,需要根据给定的排序规则对列表进行排序。这个排序规则是由函数式接口 Comparator 表示的。

我们可以使用 lambda 表达式轻松实现排序,如下所示:

List<Integer> numbers = ...; // 100 万个整数的列表
Comparator<Integer> comparator = ...; // 给定的排序规则

Collections.sort(numbers, comparator);

上面的代码使用 lambda 表达式生成了 Comparator,并将其传递给 Collections.sort 作为排序规则。

使用 Lambda 并行处理任务

我们有一个耗时的计算任务需要并行处理。我们可以使用 lambda 表达式和 parallelStream() 方法来实现并行处理,如下所示:

List<Task> tasks = ...; // 任务列表

tasks.parallelStream()
      .forEach(task -> task.execute());

上面的代码使用 lambda 表达式创建了一个任务执行器,并将其应用于任务列表中的每个任务,实现并行处理。

以上就是Lambda 表达式如何 capture 外部变量?的详细内容,更多请关注知识资源分享宝库其它相关文章!

标签:  表达式 变量 Lambda 

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。