Pages

Monday, July 1, 2019

Java 8: Accessing Variables from Lambda Expressions

1. Overview

In this tutorial, We'll learn about how to access variables from Lambda Expressions in Java 8.

Before that, We suggest you read the tutorial on Java 8 Lambda Expressions discussed in the previous tutorial.

If you already know about Lambda's, just ignore and continue reading this article.

Can we declare a variable inside Lambda Expression?

Java 8: Accessing Variables from Lambda Expressions


The answer is yes. We can declare variables as many as needed.

What do you think if lambda has a reference to another variable?

Here, We have two scenarios to know.

First, What will happen for local variables in Lambda.

Second, Non-local variables to Lambda.


Creating a Functional Interface.

@FunctionalInterface
interface BookInterface {
 int getBooksCount(String catefory);
}

Complete guide to Functional Interfaces in Java 8.

2. Local Variables To Lambda


We can declare any type of variable in a Lambda block as similar to declaring variables inside a method.

In the below example, creating a lambda expression with local variable localLamdbdaVar.

public class LambdaVariables {
 public static void main(String[] args) {

  BookInterface bookInterface = (catefory) -> {
   int localLamdbdaVar = 10; // Local Variable to Lambda and can not be accessed from outside of it.
   
   // some logic to get books count from Library for a Category.
   localLamdbdaVar++; // Incrementing value by 1.

   return localLamdbdaVar;
  };

  int count = bookInterface.getBooksCount("Technology");
  System.out.println("count " + count);
 }
}

This program compiles and runs with no errors.

Output:

count 11

If we declare the same variable outside lambda like below, it will through compile time error.

int localLamdbdaVar = 5; 
BookInterface bookInterface = (catefory) -> {
 int localLamdbdaVar = 10; // Local Variable to Lambda and can not be accessed from outside of it.
 
 // some logic to get books count from Library for a Category.
 localLamdbdaVar++; // Incrementing value by 1.

 return localLamdbdaVar;
};

Error: Lambda expression's local variable localLamdbdaVar cannot redeclare another local variable defined in an enclosing scope.

Because compiler saying error at below line inside Lambda.

int localLamdbdaVar = 10;

Already, We have outside a Lambda variable is declared with the same name. So, We can not redeclare it.

Java 8 Examples Programs Before and After Lambda & Streams

3. Non-Local To Lambda


Now, we will remove the variable localLamdbdaVar from Lambda and add it outside as below.

int localLamdbdaVar = 10; 
BookInterface bookInterface = (catefory) -> {

 // some logic to get books count from Library for a Category.
 localLamdbdaVar++; // Incrementing value by 1.

 return localLamdbdaVar;
};

Variable localLamdbdaVar is declared in enclosed scope.

At compile time it fails with reason "Local variable localLamdbdaVar defined in an enclosing scope must be final or effectively final" at localLamdbdaVar++;

Because localLamdbdaVar value is getting changed inside the lambda. It is not allowed in Lambda. Because whatever the changes are done inside Lambda is not visible to the enclosed scope.

Note: Changes are made to a variable (which is declared in enclosed scope or Outside Lambda) inside Lambda is not visible to the enclosed block. If the value is modified then enclosed block cannot find them. Because of this compile will through compile time error saying "variable must be final or effective final"

Effectively Final variable is a variable or parameter whose value isn’t changed after it is initialized.

Below is the solution using effective final variable.

int localLamdbdaVar = 10; 
BookInterface bookInterface = (catefory) -> {
 // some logic to get books count from Library for a Category.
 return localLamdbdaVar;
};

Here, Compiler considers localLamdbdaVar variable as effective final.

Note:
If we try to change the value either in the lambda itself or elsewhere in the enclosing scope, we will get an error.
No keyword is required to declare a variable as an effective final.
Enclosed variables can be used at any place in Lambda but the value can not be changed.

4. Conclusion


In this tutorial, We've seen how to access the variables in Lambda Expressions.

Learned the behavior inside and outside declaring the variables.

If the enclosed variable is not modified then it is said to be Effectively Final Variable and can be used inside Lambda.

All the code shown in this example is over GitHub.

No comments:

Post a Comment

Please do not add any spam links in the comments section.