Tuesday, March 25, 2014

Lambda Expressions and functional interface in Java 8

Lambda Expression is a new feature added to Java 8. It simplifies code by passing functions/methods directly to a method as parameters. It is used for implementing interfaces that have only one abstract method, known as functional interfaces. Since the interface has only one abstract method, when a method from another object has an argument that is the type of this interface, a lambda expression can be used to put the implementation of the functional interface, the code for overriding the abstract method of the interface, in the place of the argument of the method.

The syntax of Lambda Expressions

1. A parenthesis within which has a comma-separated list of objects/primitives which are the parameters of the abstract method that this Lambda Expression is overriding. If there is only one item in the parenthesis, the parenthesis can be removed. If the abstract method takes no argument, the empty parenthesis "()" (without the quotes) is used.

2. The right headed arrow ( -> ) that separates the parameters from the method implementation.

3. The body that implements the logic of the method.

For example:
       (int a, int b) -> a > b && (a - b) < 50
can be the implementation of such a functional interface:
       public interface Calculator {
              public boolean test(int a, int b);
      }
If you have the following code that uses the Calculator as a parameter:
      public class DecisionMaker {
            public Person getThe RightPerson (Person person1,
                                                                Person person2,
                                                               Calculator calculator) {
                    int age1 = person1.getAge(), age2 =  person2.getAge();

                   if (calculator.test(age1, age2)) {
                         return person1;
                  } else {
                         return person2;
                  }
            }
      }
Since Calculator is an interface, before Java 8, you have to create a class to implement this interface before you can use it, and you pass an instance of the implementing class to the method. However, with Lambda Expression, the implementing class can be omitted.
   
Without using Lambda Expression:
       public class MyCalculator implements Calculator {
               public boolean test (int a, int b) {
                      System.out.println("Without using lambda expression."); 
                      return (a > b && (a - b) < 50);
               }
       }
     
       DecisionMaker dm = new DecisionMaker();
       Person rightPerson = dm.getTheRightPerson(
                                                person1,
                                                person2,
                                                new MyCalculator());

Using Lambda Expression:
       DecisionMaker dm = new DecisionMaker();
       Person rightPerson = dm.getTheRightPerson(
                                                person1,
                                                person2,
                                                (int a, int b) -> {System.out.println("Using lambda expression."); return a > b && (a - b) < 50;});

Another Example

Here is another example of using Lambda Expressions. Every year, in your company, you give a special prize to those employees whose performance is over 800 and whose team's performance is over 600. You can use the following code to get a list of those that qualify for the prize.

//Create the functional interface.
//A functional interface is an interface that contains only one abstract method.
//It may have one or more static and default methods.
public interface Qualifier {
      public boolean isQualified (Employee employee, Team team);
}

//The class that does the screening
public class SpecialPrizeScreener {
      public List<Employee> getSpecialPrizeWinners(List<Employee> allEmployees,
                                          List<Team> teams,
                                          Qualifier qualifier) {

            List<Employee> result = new ArrayList<Employee>();
         
            for (Employee employee : allEmployees){
                  for (Team team : teams) {
                         if (team.contains(employee)) {
                                if (qualifier.isQualified(employee, team) {
                                       result.add(employee);
                                }
                         }
                   }
   }
            return result;
      }

      public static void main(String[] args) {
            SpecialPrizeScreener screener = new SpecialPrizeScreener();
            List<Employee> allEmployees = <your method to get all your employees>;
            List<Team> teams = <your method to get all the teams>;

            //The method name can be omitted in Java 8 when implementing a functional interface.
            //Thus, the Lambda Expression can be used in implementing the functional interface
            //and used directly as a parameter of the method call.
            List<Employee> specialPrizeWinners = screener.getSpecialPrizeWinners (
                        allEmployees,
                        teams,
                        (Employee employee, Team team) -> employee.getPerformance() > 800
                                                        && team.getPerformance() > 600);

      }
}

Using generic functional interface

//Create the functional interface that takes generics
public interface Qualifier<K, V> {
      public boolean isQualified (K param1, V param2);
}

//Modify the getSpecialPrizeWinners method in the SpecialPrizeScreener class to let the Qualifier take Employee and Team as its generic types.

      public List<Employee> getSpecialPrizeWinners(List<Employee> allEmployees,
                                          List<Team> teams,
                                          Qulifier<Employee, Team> qualifier)

//In the above Lambda Expression, the parameter types can be omitted.
List<Employee> specialPrizeWinners = screener.getSpecialPrizeWinners (
                        allEmployees,
                        teams,
                        (employee, team) -> employee.getPerformance() > 800
                                                        && team.getPerformance() > 600);

Using multiple Lambda Expressions

//You may use as many as Lambda Expressions in a method wherever it is possible
//You may modify the above code to add another Lambda Expression.

//Using the functional interface Consumer<T> interface
public interface Consumer<T> {
      public void accept(T t);
}


public class SpecialPrizeScreener {
      public void getSpecialPrizeWinners(List<Employee> allEmployees,
                                          List<Team> teams,
                                          List<Employee> result,
                                          Qulifier qualifier,
                                          Consumer<Employee> consumer) {

            for (Employee employee : allEmployees){
                  for (Team team : teams) {
                         if (team.contains(employee)) {
                                if (qualifier.isQualified(employee, team) {
                                       consumer.accept(employee);
                                }
                         }
                   }
   }
      }

      public static void main(String[] args) {
            SpecialPrizeScreener screener = new SpecialPrizeScreener();
            List<Employee> allEmployees = <your method to get all your employees>;
            List<Team> teams = <your method to get all the teams>;
            List<Employee> result = new ArrayList<Employee>();

            //implementing the additional Lambda Expression
            screener.getSpecialPrizeWinners (
                        allEmployees,
                        teams,
                        result,
                        (employee, team) -> employee.getPerformance() > 800
                                                        && team.getPerformance() > 600,
                        employee -> result.add(employee));

      }
}

------------------------------------------------------------------------------------------------------------------

                        
If you have ever asked yourself these questions, this is the book for you. What is the meaning of life? Why do people suffer? What is in control of my life? Why is life the way it is? How can I stop suffering and be happy? How can I have a successful life? How can I have a life I like to have? How can I be the person I like to be? How can I be wiser and smarter? How can I have good and harmonious relations with others? Why do people meditate to achieve enlightenment? What is the true meaning of spiritual practice? Why all beings are one? Read the book free here.

1 comment: