Tuesday, 14 July 2015

JAVA 8 Features


  • Default interface declaration
  • Lambda expressions
Java 8 has introduced a new feature called Lambda expressions.It is considered to be a major change in java. As this change will bring functional programming into java. Other languages such as Scala already have this feature so this is not new to programming world, it is new to java.

Before understanding Lambda expressions, Lets first understand Functional Interface.

What is Functional Interface?

Functional interfaces are those interfaces which have only one abstract method in it. It can have more than one default or static method and can override method from java.lang.object. Lets create a functional interface:
  1. @FunctionalInterface  
  2. public interface Decorable {  
  3.   
  4.  // one abstract method  
  5.  void decorateWithCurtains();  
  6.    
  7.  // default method  
  8.  default void decorateWithPaints()  
  9.  {  
  10.   System.out.println("Decorating using paints");  
  11.  }  
  12.   
  13.  // Overriding method of java.lang.Object  
  14.  @Override  
  15.  public int hashCode();  
  16.   
  17. }   

Java can itself identify Functional Interface but you can also denote interface as Functional Interface by annotating it with @FunctionalInterface.

Some popular Functional Interfaces are:
  • java.lang.Runnable
  • java.util.concurrent.Callable
  • java.awt.event.ActionListener
  • java.util.Comparator

Why Lambda Expressions?

Lets understand with help of  Anonymous Comparator:
  1.          Country indiaCountry=new Country(1"India");  
  2.          Country chinaCountry=new Country(4"China");  
  3.          Country nepalCountry=new Country(3"Nepal");  
  4.          Country bhutanCountry=new Country(2"Bhutan");  
  5.           
  6.          List<Country> listOfCountries = new ArrayList<Country>();  
  7.          listOfCountries.add(indiaCountry);  
  8.          listOfCountries.add(chinaCountry);  
  9.          listOfCountries.add(nepalCountry);  
  10.          listOfCountries.add(bhutanCountry);   
  11.   
  12.          //Sort by countryName  
  13.   
  14.             Collections.sort(listOfCountries,new Comparator<Country>() {  
  15.   
  16.                 @Override  
  17.                 public int compare(Country o1, Country o2) {  
  18.   
  19.                     return o1.getCountryName().compareTo(o2.getCountryName());  
  20.                 }  
  21.             });  

The problem with Anonymous Comparator is of syntax. Each time you want to sort list using comparator, you have to remember bulky syntax.
So generally main problem with Anonymous classes are syntax.For very simple operation, we need to write complex code. To solve this problem, JDK has introduce new feature called Lambda Expressions.I will take this example after explaining lambda expression to understand , how lambda expression will reduce this complex code.

What is Lambda Expressions:

lambda expression represents an anonymous function. It comprises of a set of parameters, a lambda operator (->) and a function body .You can call it function without name,

Connection between Lambda Expression and Functional Interface:
You might be thinking I have introduced functional Interface above but how it is connected to Lambda.So Lambda expression can be applied for abstract method of functional Interface which is being implemented or being instantiated anonymously.

Structure of Lambda Expressions

  1. (Argument List) ->{expression;} or  
  2. (Argument List) ->{statements;}    

So we can divide structure of Lambda expression to three parts:
  1.  Argument list or parameters
    • Lambda expression can have zero or more arguments.
      1. ()->{System.out.println("Hello")}; //Without argument, will print hello   
      2. (int a)->{System.out.println(a)} //; One argument, will print value of a  
      3. (int a,int b)-> {a+b};//two argument, will return sum of these two integers  
    • You can choose to not declare type of arguments as it can be inferred from context.
      1. (a,b)->{a+b};//two argument, will return sum of these two numbers  
    • you can not declare one argument's type and do not declare type for other argument. 
      1. (int a,b)->{a+b};//Compilation error   
    • When there is a single parameter, if its type is inferred, it is not mandatory to use parentheses
      1. a->{System.out.println(a)}; // Will print value of number a   
  2. Array token (->)
  3. Body
    • Body can have expression or statements.
    • If there is only one statement in body,curly brace is not needed and return type of the anonymous function is same as of  body expression
    • If there are more than one statements, then it should be in curly braces and return type of anonymous function is same as value return from code block, void if nothing is returned.
Lets take some examples ,  you want to initialize thread and now you will realize, how can lambda expression can make your coding easy :
  1. public class ThreadSample {  
  2.   
  3.  public static void main(String[] args) {  
  4.     
  5.   // old way  
  6.   new Thread(new Runnable() {  
  7.      
  8.    @Override  
  9.    public void run() {  
  10.     System.out.println("Thread is started");  
  11.    }  
  12.   }).start();  
  13.   
  14.   // using lambda Expression  
  15.   new Thread(()->System.out.println("Thread is started")).start();  
  16.  }  
  17.   
  18. }  

Lets take another example of Comparator which we have seen in Anonymous Comparator in java.
Create a class called Country.java
  1. package org.arpit.java2blog;  
  2.   
  3. public class Country{  
  4.     int countryId;  
  5.     String countryName;  
  6.       
  7.     public Country(int countryId, String countryName) {  
  8.         super();  
  9.         this.countryId = countryId;  
  10.         this.countryName = countryName;  
  11.     }  
  12.   
  13.     public int getCountryId() {  
  14.         return countryId;  
  15.     }  
  16.     public void setCountryId(int countryId) {  
  17.         this.countryId = countryId;  
  18.     }  
  19.     public String getCountryName() {  
  20.         return countryName;  
  21.     }  
  22.     public void setCountryName(String countryName) {  
  23.         this.countryName = countryName;  
  24.     }  
  25. }   
Create a main class called ComparatorMain.java
  1. package org.arpit.java2blog;  
  2.   
  3.   
  4. import java.util.ArrayList;  
  5. import java.util.Collections;  
  6. import java.util.Comparator;  
  7. import java.util.List;  
  8.   
  9. public class ComparatorMain {  
  10.   
  11.  /** 
  12.   * @author Arpit Mandliya 
  13.   */  
  14.  public static void main(String[] args) {  
  15.   Country indiaCountry=new Country(1"India");  
  16.   Country chinaCountry=new Country(4"China");  
  17.   Country nepalCountry=new Country(3"Nepal");  
  18.   Country bhutanCountry=new Country(2"Bhutan");  
  19.   
  20.   List<country> listOfCountries = new ArrayList<country>();  
  21.   listOfCountries.add(indiaCountry);  
  22.   listOfCountries.add(chinaCountry);  
  23.   listOfCountries.add(nepalCountry);  
  24.   listOfCountries.add(bhutanCountry);  
  25.   
  26.   System.out.println("Before Sort by name : ");  
  27.   for (int i = 0; i < listOfCountries.size(); i++) {  
  28.    Country country=(Country) listOfCountries.get(i);  
  29.    System.out.println("Country Id: "+country.getCountryId()+"||"+"Country name: "+country.getCountryName());  
  30.   }  
  31.   
  32.   //Sort by countryName  
  33.   // Anonymous Comparator  
  34.   // old way  
  35.   Collections.sort(listOfCountries,new Comparator<country>() {  
  36.   
  37.    @Override  
  38.    public int compare(Country o1, Country o2) {  
  39.     return o1.getCountryName().compareTo(o2.getCountryName());  
  40.    }  
  41.   });  
  42.     
  43.   // Using lambda expression  
  44.   Collections.sort(listOfCountries,(o1,o2)-> o1.getCountryName().compareTo(o2.getCountryName()));  
  45.     
  46.   System.out.println("After Sort by name: ");  
  47.   for (int i = 0; i < listOfCountries.size(); i++) {  
  48.    Country country=(Country) listOfCountries.get(i);  
  49.    System.out.println("Country Id: "+country.getCountryId()+"|| "+"Country name: "+country.getCountryName());  
  50.         
  51.    }  
  52.  }  
  53.   
  54. }  
As you can see here, we have used lambda expression for using Comparator. SO inspite of wrting Anonymous comparator, our expression became very easy.











So we have passed 2 arguments o1 and o2, we didn't pass type because it can inferred from context.
We have only one statement here, so no need to put it in curly braces.

Lets create HelloWorld Lambda Expression Example:

Create an Interface Called HelloWorld:
  1. package org.arpit.java2blog;  
  2.   
  3. public interface HelloWorld {  
  4.  void sayHello();  
  5. }  
Create a class called HelloWorldMain
  1. package org.arpit.java2blog;  
  2.   
  3. public class HelloWorldMain {  
  4.   
  5.  public static void main(String args[])  
  6.  {  
  7.                 // Lambda Expression   
  8.   HelloWorld helloWorld=()->System.out.println("Hello using Lambda Expression");  
  9.   helloWorld.sayHello();  
  10.  }  
  11. }  
Run above program you will get following output:
  1. Hello using Lambda Expression  

No comments:

Post a Comment