Lambda Expressions in Java

Java is a first-class object-oriented language. With the exception of primitive data types, everything in Java is an object. Even an array is an Object. Every class creates instances that are objects. There is no way of defining just a function / method which stays in Java all by itself. There is no way of passing a method as argument or returning a method body for that instance.

Since the old days of Swing, we always had written anonymous classes if we wanted to pass some functionality to any method. For example the old event listener code used to look like:

Here we wanted to add some custom code to Mouse listener. We defined an anonymous inner class MouseAdapter and created its object. This way we passed some functionality to addMouseListener method.

In short, it is not easy to pass plain methods / functionalities in Java that can be passed as arguments. Due to this limitation Java 8 adds a brand new language level feature called Lambda Expressions.

Why Java needs Lambda Expressions?
Since its beginning, the Java language hasn’t evolved much if you ignore some of the features like Annotations, Generics etc. Mostly during its life Java always remained Object first language. After working with functional language like JavaScript, it becomes clear to one how Java enforce its strict object-oriented nature and strict typed on the source code. You see Functions are not important for Java. On their own they cannot live in Java world.


Functions are first class citizens in a functional programming language. They exists on their own. You can assign them to a variable and pass them as arguments to other functions. JavaScript is one of the best example of an FP language. There are some good articles here and here that clearly describes the benefits of JavaScript as a functional language. A functional language provides very powerful feature called Closure that has quite a few advantages over traditional way of writing applications. A closure is a function or reference to a function together with a referencing environment — a table storing a reference to each of the non-local variables of that function. Closest thing that Java can provide to Closure is Lambda expressions. There is significant difference between a Closure and Lambda expression, but at least Lambda expression provides a good alternative to Closure.

Lambda expression adds that missing link of functional programming to Java. Lambda expression let us have functions as first class citizen. Although this is not 100% correct, we will shortly see how Lambda expressions are not closures but they are as much close as we can get to closures. In languages that support first class functions, the type of the lambda expression would be a function; but in Java, the lambda expressions are represented as objects, and so they must be bound to a particular object type known as a functional interface. We will see in detail what Functional interface are.

What are Functional Interfaces
In Java, a Marker interface is an interface with no methods or fields declaration. In simple words, marker interface is an empty interface. Similarly, a Functional Interface is an interface with just one abstract method declared in it.

java.lang.Runnable is an example of a Functional Interface. There is only one method void run() declared in Runnable interface. Similarly ActionListener interface is also a Functional Interface. We use Anonymous inner classes to instantiate objects of functional interface. With Lambda expressions, this can be simplified.

Each lambda expression can be implicitly assigned to one of the interface called Functional interface. For example we can create Runnable interface’s reference from lambda expression like below:

This type of conversion is automatically taken care by compiler when we dont specify the functional interface. For example:

So in above code, compiler automatically deduced that lambda expression can be casted to Runnable interface from Thread class’s constructor

Introduction to Lambda Expressions

A lambda expression is an anonymous function (not 100% true for Java but lets assume it for time being). Simply put, it’s a method without a declaration, i.e., access modifier, return value declaration, and name.

It’s a shorthand that allows you to write a method in the same place you are going to use it. Especially useful in places where a method is being used only once, and the method definition is short. It saves you the effort of declaring and writing a separate method to the containing class.

Lambda Expressions in Java is usual written using syntax (argument) -> (body). For example:

Following are some examples of Lambda expressions.

Structure of Lambda Expressions
Let’s check the structure of lambda expressions.

A lambda expression can have zero, one or more parameters.
The type of the parameters can be explicitly declared or it can be inferred from the context. e.g. (int a) is same as just (a)
Parameters are enclosed in parentheses and separated by commas. e.g. (a, b) or (int a, int b) or (String a, int b, float c)
Empty parentheses are used to represent an empty set of parameters. e.g. () -> 42
When there is a single parameter, if its type is inferred, it is not mandatory to use parentheses. e.g. a -> return a*a
The body of the lambda expressions can contain zero, one or more statements.
If body of lambda expression has single statement curly brackets are not mandatory and the return type of the anonymous function is the same as that of the body expression.
When there is more than one statement in body than these must be enclosed in curly brackets (a code block) and the return type of the anonymous function is the same as the type of the value returned within the code block, or void if nothing is returned.

Examples of Lambda Expressions :

The following are examples of lambda expressions bound to a target type:

See the Java documentation for the new java.util.function package to get more details on these functional interfaces and their corresponding abstract methods.

Notice that the type of the lambda expression is determined by the compiler from the context based on the target type. This implies that two apparently equal lambda expressions may have different types simply because they are bound to a different target type as demonstrated in the following code.

More about lambda expressions can be learned at Oracle site.