如何在Lambda表达式中使用变量?代码举例讲解

Lambda 表达式可以访问包围作用域中的变量,这使得 Lambda 表达式的行为可以根据外部变量的状态进行变化。但是,Lambda 表达式对变量的访问也有一定的要求:

  1. Lambda 表达式只能访问 final 或 effectively final 变量。
    effectively final 变量指的是在 Lambda 表达式中虽未使用 final 关键字声明,但其值在 Lambda 表达式创建后不再改变的变量。
    例如:
int num = 1;  // effectively final 变量
Consumer<Integer> consumer = (x) -> System.out.println(x + num);

num = 2; // 错误,这会使 num 失去有效的最终性
  1. Lambda 表达式不能重新声明或隐藏包含作用域中的变量。
    例如:
int num = 1;
Consumer<Integer> consumer = (x) -> {
    int num = 2; // 错误,重复声明会隐藏外部变量
    System.out.println(x + num); 
}; 
  1. 只有当变量是可见的(不是 private 的)才能在 Lambda 表达式中访问。
    例如:
public int num = 1; 
Consumer<Integer> consumer = (x) -> System.out.println(x + num); // 正确

private int num = 1;
Consumer<Integer> consumer = (x) -> System.out.println(x + num); // 错误,num 是 private 的
  1. 在 Lambda 表达式中访问的变量的值是创建 Lambda 表达式时的值。
    例如:
int num = 1;
Consumer<Integer> consumer = (x) -> System.out.println(x + num);
num = 2;
consumer.accept(1);  // 输出 2

这里 num 的值在 Lambda 表达式创建时为 1,所以输出为 2,而不是 3。

总之,Lambda 表达式可以访问外部变量,但是有一定的限制条件。我们要充分理解这些条件,在使用时避免一些潜在的错误。