lambda 表达式只能访问外部 final 变量或 effectively final 变量(lambda 执行期间值不变的变量)。如非 final 可通过 capture variable 技术访问外部变量。该技术会创建 final 变量,并将外部变量值赋给它,确保 lambda 可访问并使用该值。
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 外部变量?的详细内容,更多请关注知识资源分享宝库其它相关文章!
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。