Java 8 — Local Variables and Lambdas

Let’s break down how to consume local variable with lambda functions in java

The following scenarios will be covered,

  1. Lambda consumes local variable initialized in a method
  2. Local variable initialized in the Lambda function
  3. Manipulating local variable inside the lambda function
  4. Manipulating local variable outside the lambda function
  5. Lambda functions consuming local reference variable
  6. Declaring variables inside the lambda function
  7. Using This in Lambda
  8. Naming Convention in Lambda

Lambda and Local Variables

Let’s take the case where a variable is being consumed by Lambda

Let’s take a class (Doge) that consumes a Functional Interface (PrintCoin) which prints the number of coins.

The Functional Interface look like this, which takes a single abstract method print()

The Class Doge looks like this, we define the function as

() -> System.out.println("Hey Gurl! I see dem coins. I got "+coin+" coins");

which gets mapped to print()

The output will look like this

Super simple! The lambda just consumes the static value.

Voila! It just gets super easy from here!

Local variable initialized in a method

Just like in the above example, the local variable coin is consumed by the lambda,

Output

Local variable initialized in the Lambda function

Now let’s try and change the variable inside the lambda function

Output

Whoa! What just happened?

Let’s break down all the questions scramming in our heads!

What is effectively final?

Without having to explicitly say that a variable is final, i.e unlike

final int number = 30;

where we have explicitly declared final. Incase of effectively final we won’t have to declare final keyword.

Final variable insinuates that it’s a constant and will never change. The same applies for effectively final. Except the compiler now can understand that it’s final without us having to explicitly write the final keyword it. Which means after initialization the value will never change.

Why do local variables need to be final or effectively final?

To ensure that no concurrency issues occur.

How can concurrency issues occur because of local variables?

Let’s say multiple threads are working on the method. Maintaining a consistent value for the variable gets difficult. The value of the variable is unpredicatble. Depending on the thread executing the value changes. So to deal with concurrent operations the local variables are final or effectively final.

Does this occur for static and instance variables too (Instance Variable, Static Variable)?

NOPE!

Why does it not occur for Static or Instance Variables?

Let’s talk about the memory storage of the variables,

Instance variables are stored in the heap area. Static variables previously were stored in PermGen (method area) and now in Metaspace. Local variables are stored on the stack.

What does this have got to do?

The stack reference is unique to each thread so the local variables are not common to each thread, whereas instance and static variables are commonly available and at all times their values will be consistent for each thread. In short, the location of where the variables are being placed is the reason why static and instance variables don’t face the issue.

Manipulating local variable outside the lambda function

Let’s have the lambda consume coin, but let’s manipulate the value outside the lambda as shown,

Output?

Yuck! Again?

Why?

As stated above the local variables in lambdas are final or effectively final. Which ensures that the values consumed will always be consistent in a multithreaded environment.

Okay!

What if the lambda does not consume the variable?

Then it works like a normal local variable. As shown below.

The output looks like this,

Sweet!

Manipulating Local Variables inside Lambda Functions

Let’s manipulate the value of coin inside the lambda function now,

Output?

Why?

You know it! It’s the same reason all over! EFFECTIVELY FINAL/FINAL, CONCURRENCY Blah Blah!

Lambda functions consuming local reference variable

Final refers that once initialized we can’t reinitialize.

The same works for reference we can initialize it once but no reinitialization is allowed.

Output is the same ole,

No reinitialization allowed for finals/effectively final!

How to manipulate the local variables of a method, that get’s consumed by Lambda function?

Can use Atomic References eg, AtomicIntegers which ensures concurrency. Although we shouldn’t be manipulating local variables inside lambdas.

Can we add values to references?

Don’t get confused!

Final ensures that the reference never changes, the value can change! As shown below.

The output looks like this,

Yay!!

Declaring Variables Inside Lambda Function

Can we declare variables inside Lambda Function? HELL YEAH!

In the above example, we had done it too! Let’s dig down

Output,

Can we manipulate the local variable declared inside the lambda function? YES YES AND YES! It’s not final!

Output,

Similarly, let’s see with references,

Output,

Worked!

This in Lambda

This refers to the current outer reference. Unlike Anonymous classes

Output

How to access the local variable? Remove this! Easy!

Output,

Naming Convention in Lambda

The local variable name defined inside the method and the local variable name defined inside the lambda function cannot be the same!

Output

The local variable name defined inside the method and the parameter name of the lambda function cannot be the same!

Output

You’ve aced Lambdas yay!

That’s all folks!

Play around more! Do Let me know if I missed any scenarios.

Cheers!

Come explore the world of programming with me!