In the first post of this series we will look at the basics of how a lambda expression is formed and what do they bring to the table.
My initial thoughts
Java 8 introduced us the exciting world of functional programming.
For a long time my reaction to this, was “Ok..one day I will look into that”, as if it was some minor thing that wouldn’t bring anything important to my world.
I was wrong.
Recently I needed to study this “lambda things” due to the OCP exam, and as I studied and documented my learnings, I started to understand the importance of lambda expressions, and how my code could improve significantly by using them.
It wasn’t an easy process, I must admit, as my head was formatted to think in an object oriented approach and functional programming is a completely new paradigm.
I the next few posts, I will try to resume and organize the notes I took while studying and learning the subject. Please have in mind that I will not use streams in the examples through out this lambda series. I will cover streams in another series dedicated to the subject.
Understanding “the why” lambda expressions.
Up to Java 7 everything was an object. All the code was in someway “linked” to a class and all functionality was inside methods, which we could pass values or objects to, in order to perform some action.
We couldn’t imagine something living in isolation (without belonging to a method in a class) that would create an action.
To understand the reason behind the need for lambda expressions, I will start with a very small and very simple example in traditional Java code.
Problem : The engineering team is building a camera that recognizes the gender of the persons.We want to create a service that can salute a person when she enters the building.
Great that sounds easy..So let’s go.
We start coding our service and we come up with
1 | public class SalutationService { |
Our main app, its also very straightforward, so we code :
1 | public class App { |
Ok..We’ve done it. It runs and salutes the gentleman that comes into the building (here represented by printing a message to the console).
But our code it’s quite stupid.
What if a lady is entering the building ?
Before our company gets sued by some organization for gender equality, we’ve better solve the problem and make sure that the camera, being built by our mates will work properly with our service.
Now we have two options we can choose from.
- We could add an argument to our salute method in the SalutationService and, based on that, we could do an If statement or setup a case machine with a switch.
But that is poor design and is driving us directly to a possible maintenance hell. Let’s suppose that later we want to salute children and eventually several genders of aliens, that in the mean time have arrived to Earth !! We will end up with a bunch of If statements, that will be difficult to maintain and expand.
Or
- Go by the book, using an Object Oriented approach, to ensure that in future we can expand and maintain our code without many complications.
As we are smart, we go for the second option. We follow the best practises, program for the interface and make use of polymorphism.
We start by creating the Salutation interface,
1 | public interface Salutation { |
then we create the GentsSalutation and LadiesSalutation classes, both implementing the Salutation interface,
1 | public class GentsSalutation implements Salutation { |
1 | public class LadiesSalutation implements Salutation { |
Ok…We are getting there…Now we need to change our SalutationService, so it becomes,
1 | public class SalutationService { |
Finally we adapt our app class to reflect the changes, so it becomes
1 | public class App { |
We test it..and it does work.This looks much better.
Now our SalutationService has a method that receives a Salutation object.
Each Salutation object will have it’s own implementation of how to perform the salutation, so we can now create classes for whatever type of salutation we may need in the future. As long as the class implements the Salutation interface, we are good to go.
We’re happy. Job Done. We head for the weekend for a deserved rest after such a tremendous amount of work.
While by the pool drinking a Margarita , we start wondering that what we’ve done, was indeed a tremendous amount of work. Creating a lot of classes just for transporting around the action of performing a salutation, based on the gender.
Ah..if we could only transport around the action directly, without the need to create a class, wouldn’t that be great ?
By now the margarita takes effect and we fell asleep dreaming with passing around actions and behaviors in Java code without the need to create all those extra classes.
Welcome to Lambda expressions
Lambda expressions allow us to create independent entities (by independent, I mean they do not belong to a class) which we will call functions.
And the best thing is that we can treat them as values, so we can pass them around.
Those entities are simply blocks of code.
Wait…are we talking about attributing a block of code to a variable ? Like
variableName={
...
...some Java code
...
}
Yes we are.
That is the main idea behind a lambda expression (function), and now we are going to examine how we can transform a method into a function.
If we take our previous example and apply to it what I’ve just said than what we want would be something like,
gentsSalutation=public void perform () {
System.out.println(“Hello dear sir");
}
But how can we do that ? How is a lambda expression formed ?
A lambda expression is formed by getting rid of everything we do not need until we get the most concise unit of code that can actually perform the action we want.
Let’s focus on the block of code that we’ve assigned above to the gentsSalutation variable.
Does the keyword public makes any sense here ?
This is not a method in a class, so the access modifier does not makes any sense. All we want is to condense the code to it’s core functionality. So we get rid of the modifier, and we now have,
Wait..we now have two names..
the variable name gentsSalutation and the method name perform.
It is quite obvious that we want to refer to this piece of code by the variable name gentsSalutation. So the method name is redundant.
Off it goes, and now we get
By now we are in a code deleting spree…
Do we need void ?
We know that void its the return type, but Java 8 compiler has become quite smart and it can now infer the return type just by looking at our code.
In this case, our code doesn’t return anything, the Java 8 compiler understands that…Great..let’s get rid of it.
Fantastic..What about the () ?
Well, those we need.
In our extremely simple example, we are not passing any parameters to the function, but we can do that, and we will see how to do that…later.
For now, we can say that we have isolated the bare minimum piece of code that performs the action we want.
For Java to understand that we want to use a lambda expression we need to add an extra element, and that is the element that identifies a lambda. The - >
By adding it to expression it becomes,
Lambdas also have some syntactic rules, and some of them allow us to condense even further our code.
Let’s now introduce the rule Number 1
If the code between the curly braces is only one line, then we can get rid of the curly braces.
By applying that rule we end up with
And there you go. This are the basics of how lambda expressions are formed.
• Take a method.
• Remove the access modifier.
• Remove the name of the method.
• Remove the return type.
• add the -> to identify this is a lambda expression.
• Remove the curly braces if the block of code only has one line.
It may take some time for our minds to get used to write lambda expressions directly. As you have seen there is no black magic of rocket science in that. It’s just a different approach of what we where used to do.
But Wait…This does not work in Java !!!!!
What is the type of the gentsSalutation variable ???
We will see that in my next post, where I will introduce Functional Interfaces.
happy coding.