10. Lambda Expressions
Programming Project 2021/22

10.4. Local Variables in Lambda Expressions

A lambda expression does not define a new scope, it inherits its enclosing one.

We can access local variables within our lambda expressions.

public static void main(String[] args) {
  int multiplier = 2;
  List.of(1, 2, 3, 4).forEach(x -> System.out.println(x * multiplier));
}

But we cannot modify their value.

int sum = 0;
// This will not compile!
List.of(1, 2, 3, 4).forEach(x -> sum += x);

We also cannot redeclare a variable.

public static void main(String[] args) {
  int value = 2;
  List.of(1, 2, 3, 4).forEach(x -> {
    int value = x;
    System.out.println(x);
  });
}

The local variables we use within our lambda bodies should be either

  • final, that is, variables whose values cannot be altered, or
  • effectively final, that is, variables whose values are not altered after initialization.

Note that the object referenced by a variable may be modified within a lambda expression.

class Accumulator {
  int value;

  public Accumulator(int value) {
    this.value = value;
  }

  void add(int value) {
    this.value += value;
  }
}

public class ModifyingObjects {
  public static void main(String[] args) {
    Accumulator acc = new Accumulator(0);
    List.of(1, 2, 3, 4).forEach(x -> acc.add(x));
  }
}