CodeX
Published in

CodeX

What Are Java 8 Lambda Expressions

A lambda expression is an unnamed block of code with optional parameters
that can be stored, passed around, & executed later.

Photo by Ignacio Amenábar on Unsplash
new Thread( 
() -> System.out.println("hello world")
).start();

This example, The Thread constructor expects an instance of Runnable. Equivalent without lambda would be,

new Thread(new Runnable() {
@Override
public void run() {
System.out.println("hello world 2");
}
}).start();

() input parameters
-> Arrow separates the param list from the lambda body.
System.out.println(“hello world”) The lambda body defines the computation.

Lambda expressions can work with multiple parameters in a much more compact manner than anonymous inner classes.They just focus on computation(s) to perform.

Behavior parameterization

Java’s lambda expressions support concise “behavior parameterization.”, essentially taking a block of code and making it available without executing it. It can be passed to a method for example. Since Java 8 introduced lambdas (finally), it is now possible to parameterize method’s behavior with anonymous functions.

Lambda as a parameter

You can also store a lambda expression into a variable & pass that variable to a method.

Runnable r = () -> System.out.println("hello world 3");
new Thread(r).start();

Effectively final

Java 8 has also introduced a new concept called “effectively final” variable. A non final local variable or method parameter whose value is never changed after initialization is known as effectively final. prior to Java 8, we cannot use a non final local variable in anonymous class. Still the variable must be final but not required to use final keyword and if the rule is violated error is thrown.

String answer="Nuwan";
new Thread(() ->
System.out.println("The answer is " + answer))
.start();

This lambda expression can access the value of “answer,” which is an effectively final variable whose value never changes after it’s initialized.

If you try to change the answer will get an error.

//will not compile
String answer="Nuwan";
new Thread(() ->
System.out.println("The answer is " + answer))
.start();
answer="change";

Stateless

Lambda expressions are most effective when they are “stateless” & have no
shared mutable data. Stateless lambda expressions are particularly useful when applied to Java parallel streams.

When implementing parallelism in collections automatic synchronization is added to make it thread-safe. However synchronization introduces thread contention which prevents threads running in parallel. Hence benifits of parallelism can be achieved when collection are not modified.

http://henrikeichenhardt.blogspot.com/2013/06/why-shared-mutable-state-is-root-of-all.html

Type Inference

Type inference is a Java compiler’s ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applicable.

lambda expression omits the method name & extraneous syntax.

List<String> list = new ArrayList<>();
list.forEach(s -> System.out.println(s));

You can see type information of s in the lambda is missing, in this example as the list is of strings s also will be a string.

Closures

Lambda expressions can implement (simplified) variants of “closures”. A closure is an object storing a method together w/an environment that has least one bound variable. A bound variable is name that has a value , such as a number or a string.

private static void closures() {
Name name = new Name();
name.value="Nuwan";
new Thread(() ->
System.out.println("The answer is " + name.value))
.start();
name.value="Chamara";
}

private static class Name{
public String value;
}

If you compare this with sample given at effectively final, this is does what we failed before. It’s because value passed to the lambda is a reference type and as long as reference is fixed Lambda will not complain.

https://dzone.com/articles/java-8-lambas-limitations-closures

Method References

Method references are not Lambda expressions but they having a similar behavior of Lambdas. Method references will use “::” instead of “->” in Lambda’s.

Method references convert Lambda’s into more readable format by creating a separate method with a name. Using method references can make our code cleaner, more readable & promote code re-usability. It’s therefore good practice to use method references whenever you can!

Functional Interfaces

A functional interface is an interface that contains only one abstract method. Type used for a parameter when a lambda expression or method reference is passed as an argument to a method.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Nuwan Zen

Nuwan Zen

Sometimes A software Engineer, sometimes a support engineer, sometimes a devops engineer, sometimes a cloud engineer :D That’s how the this life goes!