Understanding JAVA 8 Lambda Expression- Functional Programming in JAVA 8- Part 1

Understanding JAVA 8 Lambdas- Functional Programming in JAVA 8- Part 1

Why Lambdas?….Lambdas is a new programming construct which lets you build JAVA applications in a completely different paradigm. So, what are the advantages that lambdas bring to the table:-

Lambdas enables Functional programming in JAVA, it’s actually a paradigm shift from conventional Object Oriented programming.
Readable and concise code in certain situations, removes boiler plate code.
Write better APIs which will be ultimately easier to use.
Enables support for parallel processing, which is a big thing. Every other processor nowadays is multi-core, so having support for these kinds of processors to perform parallel programming using lambdas by JAVA 8 is really a big deal.
Now the basic question arises. Why do we need Functional programming when we already have Object Oriented programming with which we can achieve almost everything?

Well, Functional programming doesn’t let you do anything new that you couldn’t do before. Functional programming just let’s you write better code, more readable code & so more maintainable code. You do agree that at the end of the day we all write machine instructions, and there is a reason why we all use High level language and not write Assembly language because it’s complex, harder to write code & so harder to maintain. Likewise, Functional programming let’s you write code which is elegant in certain situations. Functional programming is just a tool in your tool box which you will use when write kind of situation arises.

Now let’s discuss about some problems in OOP & how JAVA 7 solved those problems.In OOP, everything is an object, all code blocks are associated with classes and objects. This design is most of the times not a problem but it can be a problem sometimes. When solving your problems using JAVA code you think in terms of things & nouns rather than actions & verbs. For ex you just want to write a method which just greets say “Hello World” to console, you cannot just put a function in isolation, it has to be part of a class. You cannot have a function just be in isolation. What if somebody says, we don’t need a class we just need a function, you cannot do this in JAVA 7. Let’s write some codes.

public class Greeter {

public void greet(Greeting greeting){
System.out.println("Hello World");
}

public static void main(String[] args) {
Greeter greeter=new Greeter();
greeter.greet();
}
}

Output:- Hello World

Above greet method will always print “Hello World”. Now I want this method to take input and do different things based on the input argument. In other words I want to accept an argument and that argument tells the greet method know what to do. One way of doing this is to use switch statement, but not up to the mark, we want the behavior itself to be passed as an argument, greet method will just take the behavior & it executes it. One way of doing this in JAVA 7 is using Interface. Create a Greeting Interface which has a perform method & then you pass to the greet method an instance of Greeting Interface(implementation of Greeting Interface).

public interface Greeting {
public void perform();
}

public class HelloWorldGreeting implements Greeting {

@Override
public void perform() {
System.out.println("Hello World!");
}
}

public class Greeter {

public void greet(Greeting greeting){
greeting.perform();
}

public static void main(String[] args) {
Greeter greeter=new Greeter();
Greeting helloWorldGreeting=new HelloWorldGreeting();
greeter.greet(helloWorldGreeting);
}
}

Output:- Hello World

Same output but we are passing behavior to the greet method. You can easily create a new implementation of Greeting Interface & have a greet method do something else, classic Object Oriented feature, Polymorphism.

So, does this solves the problem? You wanted to pass in the behavior and wanted to execute that behavior. Previously our problem was solved, well kind of it does…… We are doing some extra work here. Actually we have passed a thing that has a behavior, we are passing a Greeting object that has a perform behavior(perform method). Wouldn’t it be cool that we had just passed an action rather than an object of a class that implements an action.

public void greet(action){
action();
}

Well lambdas set out to achieve just this only. Lambdas lets you create these entities which are just functions that do not belong to a class, and they exist in isolation. And, the best part is these functions can be treated as values. Hmmm, kind of confusing for those who is used to OOP & they haven’t done Functional programming.

You know what Inline values are, String name=”foo”;

“foo” is a string that has been written inline. Data acts as value in JAVA, you can assign them to different types. So, can we assign a block of code to a variable as value.

aBlockOfCode={
.....
.....
};

Piece of code becomes a value that gets assigned to a variable & wherever the variable goes that piece of code goes. Here we will be assigning the method to a variable & not executing the method & assigning the returned value. Can we do something like above? With JAVA 8 using lambdas this is possible using lambda expressions.

aBlockOfCode = public void perform() {
System.out.println("Hello World!");
}

Above is just for understanding, there are lots of extra things that we don’t need. “public” makes sense when the function is a part of class. It makes sense in the context of class. But if a function is in isolation, then it doesn’t makes sense. The function is accessible whoever has that variable. So get rid of the public access modifier.

aBlockOfCode = void perform() {
System.out.println("Hello World!");
}

When you assign a function to a variable, we will use the name of the variable to access the block of code. So get rid of the function name.

aBlockOfCode = void() {
System.out.println("Hello World!");
}

JAVA compiler now is smart enough to detect the return type of a function. So no need to specify return type.

aBlockOfCode = () {
System.out.println("Hello World!");
}

This is all left to specify lambda expression, with one small addition.

aBlockOfCode = () ->; {
System.out.println("Hello World!");
}

“->;” symbol between parenthesis & block of code. If the lambda expression has just one line of statement then remove the curly braces.

aBlockOfCode = () ->; System.out.println("Hello World!");

If multiple line of statements then use curly braces {}. Lambda expression can be assigned to a variable in JAVA 8, and this variable contains the value which is function. In the case of our example:-

greetingFunction = () ->; System.out.println("Hello World!");

You must be thinking as to what would be the type of greetingFunction variable as we are in the JAVA world? Let’s hold that thought for a bit. For now we will concentrate on right hand side. One of the advantage of having this function assigned to a variable is that this variable can be passed around. You can send this to another method as an argument and have that method have access to the function.

greet(greetingFunction);
public void greet(_______){
_______();
}

So our requirement was that the greet method will accept an action and then execute that action.We need a way so that the argument of greet method accepts our lambda expression(action). So, how to pass a lambda expression to a function & how to execute the lambda expression.

Functions are not always empty parameters, there are functions that takes arguments. Let’s write lambda expression with arguments. Let’s say we have a function which returns double of integer. We will write the method as we used to know and then we will eliminate the non-required things.

doubleNumberFunction = public int double(int a) {
return a*2;
}

This is not a lambda expression. Now we will convert it into a lambda expression.Remove the modifier as it is attached to a class.

doubleNumberFunction = int double(int a) {
return a*2;
}

Function name doesn’t make sense as we will be referring it with variable name.

doubleNumberFunction = int (int a) {
return a*2;
}

Return type not needed as compiler will automatically detect it in case of lambda expression.

doubleNumberFunction = (int a) {
return a*2;
}

This is not a lambda expression until we add “->;” symbol.

doubleNumberFunction = (int a) ->; {
return a*2;
}

Now if your lambda expression is just one liner then you can skip “{}” and also you can skip “return” keyword. JAVA compiler will look at the body of the function and return the required value. So, don’t specify return if the body of function is one liner.

doubleNumberFunction = (int a) ->; a*2;

So, above is our lambda expression which takes an integer and return double of that integer. Right hand side of “->;” is a return. Let’s do one more lambda expression which takes 2 integers and adds them and return the value.

addFunction = (int a, int b) ->; a+b;

Let’s do one more lambda expression which divides 2 integers and also make sure the the second argument is not zero. So, let’s call it safeDivideFunction.

safeDivideFunction = (int a, int b) ->; a/b;

But here we want safe division & make sure if b is not 0. For this we need to add if statement and since the number of statements has grown to more than 1 so add the {} curly braces.

safeDivideFunction = (int a, int b) ->; {
if(b==0) return 0;
return a/b;
}

Let’s perfect ourselves by doing one more lambda expression which takes a string and returns the length of characters.

stringLengthCountFunction = (String s) ->; s.length();

So after doing these examples hope you have become familiar with lambda expressions. Now it’s time to provide answers about type of lambda expression variable and how to execute a lambda expression. We will talk about that in next post.

Leave a Reply

Your email address will not be published. Required fields are marked *