Introduction to Lambda Expressions – Java8

What are Lambda Expressions?

Lambda expressions are another way of writing inline unnamed code block which performs a simple function. Not a direct analogy but if you recall anonymous classes in Java they are a way of writing inline classes. On similar lines Lambda expressions are a way to write method body inline.

They can be considered as anonymous methods, there is no need to formally define these methods but the code in the lambda expression is the body of the method.

Lambda Expression Example

If I want to write a print method which prints the content of a List of strings which is passed as an argument to a given method, we can do it in the following two ways:

Lambda Expressions

You might say, whats the difference? In fact they look quite similar. It seems both the ways of completing the above task had the same amount of code and effort.

So why do we need Lambda?

Let us try to modify our use case and print an exclamation mark (!) at the end of each string we print. Notice how the code gets modifies in both the cases.

Lambda Expressions

Pretty impressive, the changes happen at different places. The print method is not handling the change in case of lambda. It is being dictated by the caller which passes the lambda expression.

Now consider that you shipped a library with the print method and the user always needed to invoke the print method from the library and had no liberty of changing it.

In such a scenario the change was not possible solely by himself, until he chose to define a specialized class and override/overload the print method.

Things would have worsened if the class having the print method was a final class. In that case, he must contact you to make this additional change or stop using your library and get a better code.

Whereas in case of lambda, the user just changes the lambda expression in their calling code.

Syntax of Lambda Expression

Now that we know about few advantages of Lambda Expressions, let us learn out how to write them. A typical lambda expression would look like the below:

(TypeA a, TypeB b) -> { a statement or block of code to be execute};

  • There is a semi colon at the end, which means it is a statement/expression.
  • The arrow token in the middle, divides the complete expression in two parts.
  • The part at the right is the function body which will be executed for this expression. In the above example case, it was the statement to print an element from the list.
  • The part at the left is a list of formal parameters to be passed to the function body defined in the right part.
  • It is not necessary to define the types of the formal parameter.
  • We can also skip the parenthesis if there is a single formal parameter

More about Lambda Expression

  • In the previous examples we saw that lambda expressions help us modify the functionality at the caller’s end.
  • Which means, the caller governs/decides the functionality to be executed in a call.
  • Lambdas brings the functionality one level above the traditional approach.
  • This also means that a single method can be used in different context to execute different functionalities.
  • Basically we are trying to pass the whole function body to a method which just executes the body and returns results.

Execution of Lambda Expressions

In our code example, we passed the lambda expression to a print method which was expecting a Consumer<String> type argument. This argument is called the target of the Lambda Expression.

The Consumer<T> is an interface defined in the Java library and it has only one abstract method accept. Such interfaces with only one abstract method are called functional interfaces mostly annotated using @FunctionalInterface annotation.

This translates to the following statement:

A method which is written to accept a functional interface as a formal parameter readily accepts a lambda expression. Which means that a lambda expression is an implementation of a functional interface. And because we didn’t have a name for the lambda expression, this means that it is an anonymous implementation for the functional interface.

To be more precise, the lambda expression becomes the body of the only function of a functional interface. Hence, it is a compact representation for the single method classes or interfaces.

Which again translates to, the statement (String q) -> System.out.println(q+” !”) is an implemented version of the accept method of the Consumer class. So, the argument to the apply method is a string q and the body of the apply method is the System.out.println(q+” !”); statement.

How to write my own Functional Interface ?

It is pretty simple to start with, you just need to write an interface with only one abstract method, like the one below:

Now you can use it the same way, as we used the Consumer interface in our example.

Conclusion

Wee understood use cases which qualify for lambda expressions. Of course lambda expressions are not good by their own, it makes more sense and proves to be more useful only with the Functional support in Java 8.

They are also good to be used in the Streams pipeline. We will talk about Functions and Streams in coming posts.

Stay Connected and Stay Subscribed.