Wednesday, 16 March 2016

Java 8 Lambada Expression

Introduction
With Java 8 came Lambada expressions, which  they say makes Java a more functional programming. So the first question that comes to mind is What is functional programming?, Why do we need functional programming?, Is functional programming going to replace OO programming?
So lets try to answer the above in one liners with the help of google, stackoverflow, java world and other informational resources. Please note the following is not a mind dump but quick answers.

What is functional programming? So functional programming is a programming paradigm that enables the developers to develop code like expressions, that can be passed around, and combined with other code to create powerful functionality for the programs. It can be taught of as modules that can be combined together to perform very powerful functioning.

Why do we need functional programming? and more importantly why do we need it in Java? Functional programming creates more readable code that is easier to manage, and features like developer being able to pass code to methods as parameters makes it simple. For the other part of the question, the quick answer is that every programming language needs to evolve and so does Java, if Java stops evolving and introducing new programming paradigms then the only thing that will survive is the JVM.

Is functional programming going to replace OO? In my opinion functional programming has its own place and OO has its own place and in Java they work hand in hand to create wonderful code.

How to define and use Lambada Expressions? A Lambada expression is considered of a parameter, arrow and a body. In some languages lambadas are also know as closures. Two of the formats for expressing lambadas are: (parameters) -> expression; (parameters) -> {statements;} In case you try the following syntax: (String a, String b) -> {return a.concat(b);} This will create a compile time error, saying that "The target type of an expression must be a functional interface. So we first define a functional interface, which is an interface that contains only one method, and then create an expression. The following example shows how to do this.

package com.example.anonymous;

public class TestConcat {

 interface TestConcatenation { //this is the functional interface
  public String lConcat(String a, String b);
 }

 public static void main(String[] args) {
  //this is the lambada expression
  TestConcatenation c = (String x, String y) -> {
   return x.concat(y);
  };
  //finally using the lambada expression
  System.out.println(c.lConcat("this is the first string ", "second string here"));
 }
}

In your application there is no need to create a functional interface for every expression that you need to create as java.util.function package already comes with loads of predefined functional methods that can be used out of the box. Some of these functions are:
  • BiFunction <T, U, R> - where the function accepts two input parameters and one return variable.
  • LongFunction <R> - where the function accepts a long-valued argument and produces a result.
  • UnaryOperator <T> - where the function on a single operand that produces a result for the same type of operand.
There is also the Function <T, R> which can be used to define expressions, where T is the type of input parameter while R is the return type. The following is a quick example of how to use this.

  // Here Order and Box are two objects.
  // Order is the input type, while Box is the return type
  Function ex = (order) -> {
   Box b = new Box();
   b.setOrder(order);
   return b;
  };

  //here we apply the function
  ex.apply(new Order());

There are other ways in which lambada expressions are useful. Some examples of these are given below.

Implementing the Runnable or Callable Interface

Runnable runLambada = () -> {
   int i = 0;
   while (i < 100) {
    System.out.println("Value of i Is " + i);
    i++;
   }
  };

  runLambada.run();

Implementing the Anonymous Inner Classes Lets say that we have a very simple anonymous inner class similar to the one below.

public class TestAnonymousLambada {
 
 public void sayHello(GreetingsAdopted ga) {
  ga.greetByName("fdfdfd");
 }

 public static void main(String[] args) {
  TestAnonymousLambada tal = new TestAnonymousLambada();
  
  //GreetingsAdopted is an interface; in this case its functional 
  //interface as well
  tal.sayHello(new GreetingsAdopted() { 
   public void greetByName(String name) {
    System.out.println("hello jskdl " + name);
   }
  });

  GreetingsAdopted hLambada = (String name) -> {
   System.out.println("hello jskdl " + name);
  };

  tal.sayHello(hLambada);
 }

}

In the above example we also see the expression being sent to a method tal.sayHello(hLambada); Lambada's are also helpful in filtering out collections as show in the example below where the expression is a Predicate that allows to filter some information from the collection.

 //Transactions is an object that contains a field TransType
 public static Predicate isCredit() {
  return p -> p.getTransType().equalsIgnoreCase("CREDIT");
 }

And now using the predicate in filtering the collection.

//Here transMap is a HashMap that contains the transaction objects
System.out.println(transMap.values().stream().filter(isCredit()).count());

Finally, I am sure that I have not covered everything about lambada expressions in this blog, and there is a lot out there to be discovered, but I hope that this would at least give a starting point for some one in the right direction. Please do leave a comment if you like the blog.